前段时间做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 workpace
close all;clear ;clc
%% define display variables
nrows = 2;
ncols = 3;
iPlotNum = 1;
bDisp = 1;
%% 1 % load image
imgFolder = '../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 bDisp
hFig = figure;
end
if ndims(imInput)==3
imInput = rgb2gray(imInput);
subplot(nrows,ncols,iPlotNum);
imshow(imInput);title('input image');
iPlotNum = iPlotNum + 1;
end
if bDisp
subplot(nrows,ncols,iPlotNum);
imshow(imInput);title('grayscale image');
iPlotNum = iPlotNum + 1;
end
%% 2 % edge detection
% imEdge = im2bw(imInput);
imEdge = edge(imInput,'canny'); % ,[],'horizontal');
if bDisp
figure(hFig);
subplot(nrows,ncols,iPlotNum);
imshow(imEdge);title('edge map');
iPlotNum = iPlotNum + 1;
end
%% 3 % line segments fitting
filtLength = 40;
% find curves with length more than filtLength
[edgelist edgelabelim] = edgelink(imEdge, filtLength);
% fit curves using straight lines with derivative no more than 2 pixels
lines = lineseg(edgelist, 2);
% show curves with color
imRGB = label2rgb(edgelabelim,'lines','k');
if bDisp
figure(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 edges
lineDir = 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 10
indVertLines = 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 segment
midPoints = round([(vertLines(:,1)+vertLines(:,3))/2 (vertLines(:,2)+vertLines(:,4))/2]);
figure(vLineFig);
hold on;
plot(midPoints(:,1),midPoints(:,2),'yo'); % draw middle points
for i=1:numLines
% show line index number at 4 pixels above mid point
text(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 points
hold off;
%% 6 % calculate normalized distance matrix
% calculate the absolute distance
distMat = zeros(numLines);
for i=1:numLines
for j=1:numLines
% if horizonal distance exceeds the length sum of the 2 segments
if 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 contribution
distMat(i,j) = 0;
end
end
end
avergDist = mean(sum(abs(distMat(:))))./sum(distMat(:)~=0);
% threshold the distance matrix
distThresh = avergDist * 0.5 ;
distMat(abs(distMat)>distThresh) = 0;
% normalize the distance matrix using the image diagonal
distMat = distMat ./ avergDist;
%% 7 % accumulate the surrounding information
% calculate the number difference between the two sides of the contour
sideDiff = abs(sum(distMat>0,2) - sum(distMat<0,2));
% assume the line segment is infinite far from itself
distMat(distMat==0) = Inf;
%% 8 % calculate the voting values
sourdMat = zeros(numLines);
for i=1:numLines
sourdMat(i,:) = exp(-abs(sqrt(exp(sideDiff(i)))*distMat(i,:)));
end
% the probability of each to be a noise contour
resSaliencyMat = 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 segment
vCostFig = 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 point
text(midPoints(i,1),midPoints(i,2)-4,num2str(resSaliencyMat(i)),'Color','r');
end
hold off;
%% 9 % thresholding the line segments to filter the noise ones
noiseThresh = 1;
% remove noise line from original image
lines(indVertLines(resSaliencyMat > noiseThresh),:) = [];
if bDisp
figure(hFig);
subplot(nrows,ncols,iPlotNum);
showedgelist(lines,size(imEdge),1);
title('line segments after filtering');
iPlotNum = iPlotNum + 1;
end
这张图像只演示了水平方向上的边缘抑制效果。
计算结果:

相应的,各个边缘的noise probality(非严谨意义上的概率)度量为:

对这些噪声程度值设定一个阈值进行过滤,就得到第一张图片最后那张效果图了。

6784

被折叠的 条评论
为什么被折叠?



