前段時間做Contour Grouping比較糾結的一個問題是受雜訊邊緣的幹擾太厲害。
這裡說的雜訊邊緣指的是非目標的邊緣,比如我現在在做交通映像,那麼,出了車的輪廓,其他對於我來說都是雜訊映像。在實際做的時候,遇到的主要是車內部的雜訊。
於是,設計了一個通過投票來累積一個我叫做雜訊度(noise probability)的值,然後設定一個閾值去過濾,初步效果還不錯。
主要思想是:
- 觀察周圍一個閾值範圍內是否有邊緣。對於邊界來說,只有一側有,或者兩側都沒有
- 投票函數不能是距離的正比函數,因為越遠離邊緣,對其影響應該越弱,於是拿Gaussian函數拿來簡單改造一下使用;
片:
實現代碼:
% To build into contourInhibition.m% % This script is used for implementing contour noise inhibition% % Created by visionfans @ 2011.07.02%% clear workpaceclose all;clear ;clc%% define display variablesnrows = 2;ncols = 3;iPlotNum = 1;bDisp = 1;%% 1 % load imageimgFolder = '../test/car';imgFileName = '1.jpg';imInput = imread(fullfile(imgFolder,imgFileName));[nHeight nWidth nChannel] = size(imInput);iSizeRatio = 256 / nWidth;imInput = imresize(imInput,[nHeight*iSizeRatio 256]);if bDisphFig = figure;endif ndims(imInput)==3imInput = rgb2gray(imInput);subplot(nrows,ncols,iPlotNum);imshow(imInput);title('input image');iPlotNum = iPlotNum + 1;endif bDispsubplot(nrows,ncols,iPlotNum);imshow(imInput);title('grayscale image');iPlotNum = iPlotNum + 1;end%% 2 % edge detection% imEdge = im2bw(imInput);imEdge = edge(imInput,'canny'); % ,[],'horizontal');if bDispfigure(hFig);subplot(nrows,ncols,iPlotNum);imshow(imEdge);title('edge map');iPlotNum = iPlotNum + 1;end%% 3 % line segments fittingfiltLength = 40;% find curves with length more than filtLength[edgelist edgelabelim] = edgelink(imEdge, filtLength);% fit curves using straight lines with derivative no more than 2 pixelslines = lineseg(edgelist, 2);% show curves with colorimRGB = label2rgb(edgelabelim,'lines','k');if bDispfigure(hFig);subplot(nrows,ncols,iPlotNum);imshow(imRGB);title('curve segments');iPlotNum = iPlotNum + 1;subplot(nrows,ncols,iPlotNum);showedgelist(lines,size(imEdge),1);title('fitted line segments');iPlotNum = iPlotNum + 1;end%% 4 % filter out vertical edgeslineDir = atan(abs((lines(:,1)-lines(:,3))./(lines(:,2)-lines(:,4)))) .* 180 ./ pi;lineLen = sqrt((lines(:,1)-lines(:,3)).^2 + (lines(:,2)-lines(:,4)).^2);% filter out lines with direction larger than 45 and length larger than 10indVertLines = find((lineDir > 45) & (lineLen > 10));numLines = length(indVertLines);vertLines = lines(indVertLines,:);vLineFig = figure;showedgelist(vertLines,size(imEdge),1);title('vertical line segments');%% 5 % plot middle points of every line segmentmidPoints = round([(vertLines(:,1)+vertLines(:,3))/2 (vertLines(:,2)+vertLines(:,4))/2]);figure(vLineFig);hold on;plot(midPoints(:,1),midPoints(:,2),'yo');% draw middle pointsfor i=1:numLines% show line index number at 4 pixels above mid pointtext(midPoints(i,1),midPoints(i,2)-4,num2str(i),'Color','r');end% plot(lines(:,1),lines(:,2),'ro');% draw right points% plot(lines(:,3),lines(:,4),'bo');% draw left pointshold off;%% 6 % calculate normalized distance matrix% calculate the absolute distancedistMat = zeros(numLines);for i=1:numLinesfor j=1:numLines% if horizonal distance exceeds the length sum of the 2 segmentsif abs(midPoints(j,1)-midPoints(i,1)) < (lineLen(indVertLines(i))+lineLen(indVertLines(j)))/2-6% contribution distance distMat(i,j) = midPoints(j,2) - midPoints(i,2);else% no contributiondistMat(i,j) = 0;endendendavergDist = mean(sum(abs(distMat(:))))./sum(distMat(:)~=0);% threshold the distance matrixdistThresh = avergDist * 0.5 ;distMat(abs(distMat)>distThresh) = 0;% normalize the distance matrix using the image diagonaldistMat = distMat ./ avergDist;%% 7 % accumulate the surrounding information% calculate the number difference between the two sides of the contoursideDiff = abs(sum(distMat>0,2) - sum(distMat<0,2));% assume the line segment is infinite far from itselfdistMat(distMat==0) = Inf;%% 8 % calculate the voting valuessourdMat = zeros(numLines);for i=1:numLinessourdMat(i,:) = exp(-abs(sqrt(exp(sideDiff(i)))*distMat(i,:)));end% the probability of each to be a noise contourresSaliencyMat = sum(sourdMat,2);resSaliencyMat(sum(distMat>0 & distMat ~= Inf,2)==0) = 0;resSaliencyMat(sum(distMat<0 & distMat ~= -Inf,2)==0) = 0;% show noise probability of every segmentvCostFig = figure;showedgelist(vertLines,size(imEdge),1);hold on;plot(midPoints(:,1),midPoints(:,2),'yo'); for i=1:numLines% show line index number at 4 pixels above mid pointtext(midPoints(i,1),midPoints(i,2)-4,num2str(resSaliencyMat(i)),'Color','r'); endhold off;%% 9 % thresholding the line segments to filter the noise onesnoiseThresh = 1;% remove noise line from original imagelines(indVertLines(resSaliencyMat > noiseThresh),:) = [];if bDispfigure(hFig);subplot(nrows,ncols,iPlotNum);showedgelist(lines,size(imEdge),1);title('line segments after filtering');iPlotNum = iPlotNum + 1;end
這張映像只示範了水平方向上的邊緣抑制效果。
計算結果:
相應的,各個邊緣的noise probality(非嚴謹意義上的機率)度量為:
對這些雜訊程度值設定一個閾值進行過濾,就得到第一張圖片最後那張了。