基于邻域投票的噪声边缘抑制

前段时间做Contour Grouping比较纠结的一个问题是受噪声边缘的干扰太厉害。

这里说的噪声边缘指的是非目标的边缘,比如我现在在做交通图像,那么,出了车的轮廓,其他对于我来说都是噪声图像。在实际做的时候,遇到的主要是车内部的噪声。

于是,设计了一个通过投票来累积一个我叫做噪声度(noise probability)的值,然后设定一个阈值去过滤,初步效果还不错。

主要思想是:

  1. 观察周围一个阈值范围内是否有边缘。对于边界来说,只有一侧有,或者两侧都没有
  2. 投票函数不能是距离的正比函数,因为越远离边缘,对其影响应该越弱,于是拿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(非严谨意义上的概率)度量为:


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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值