Canny Edge Detection Algorithm problem?

2 views (last 30 days)
Steve
Steve on 2 Jun 2012
Hello Dear Experts,
Here is what I have written as an implementation of the Canny Edge detection algorithm but I get non accurate results. Please try to help me, what can be the reason, where did I do a mistake?
function [ newImg ] = edgeDetect( img )
% Step 0: Initialization, smoothing the matrix to eliminate the noise:
[imgRows imgCols] = size(img);
% Gaussian Filter:
GaussianFilter = fspecial('gaussian', 5, 1);
%T = T/sum(sum(T)); % Normalizing the filter
SmoothMat = conv2(img,GaussianFilter,'same'); % Smoothing
epsilon = exp(-10);
newImg = zeros(size(img));
HiT = 0.15;
LoT = 0.07;
% Step 1: Calculating the derivative of the smoothed image using convolution:
dx = conv2(SmoothMat,[-1 1],'same');
dy = conv2(SmoothMat,[-1 1]','same');
% Substep: There can be dx(i,j) = 0 and dy(i,j)/dx(i,j) will be +/-inf to
% avoid it we will add an epsilon to eliminate the +/-inf problem:
idx = dx == 0;
dx(idx) = epsilon;
% Step 2: Calculating the gradient and the angle:
GradVec = sqrt(dx.*dx + dy.*dy);
TanTheta = dy./dx;
% Avoiding the edges of the matrix - first and last rows and columns
TempGradVec = padarray(GradVec,[1 1]);
TempTanTheta = padarray(TanTheta,[1 1]);
% Step 3: Checking direction condition and gradient value along with NMS
for i = 2:imgRows+1
for j = 2:imgCols+1
if ((TempTanTheta(i,j) >= -0.4142) && (TempTanTheta(i,j) <= 0.4142))
TempGradVec(i,j) = isMax(TempGradVec(i,j-1),TempGradVec(i,j),TempGradVec(i,j+1));
elseif ((TempTanTheta(i,j) > 0.4142) && (TempTanTheta(i,j) <= 2.4142))
TempGradVec(i,j) = isMax(TempGradVec(i+1,j-1),TempGradVec(i,j),TempGradVec(i-1,j+1));
elseif (abs(TempTanTheta(i,j)) > 2.4142)
TempGradVec(i,j) = isMax(TempGradVec(i-1,j),TempGradVec(i,j),TempGradVec(i+1,j));
elseif ((TempTanTheta(i,j) >= -2.4142) && (TempTanTheta(i,j) < -0.4142))
TempGradVec(i,j) = isMax(TempGradVec(i-1,j-1),TempGradVec(i,j),TempGradVec(i+1,j+1));
end
end
end
% Step 4: The hysteresis part, using the predefined threshold values
for i = 2:imgRows-1
for j = 2:imgCols-1
if TempGradVec(i,j) > HiT
TempGradVec(i,j) = 1;
elseif TempGradVec(i,j) < LoT
TempGradVec(i,j) = 0;
elseif TempGradVec(i,j-1) == 1 ||...
TempGradVec(i-1,j) == 1 ||...
TempGradVec(i-1,j+1) == 1 ||...
TempGradVec(i,j-1) == 1 ||...
TempGradVec(i,j+1) == 1 ||...
TempGradVec(i+1,j-1) == 1 ||...
TempGradVec(i+1,j) == 1 ||...
TempGradVec(i+1,j+1) == 1
TempGradVec(i,j)=1;
TempGradVec(i,j)=1;
else
TempGradVec(i,j)=0;
end
end
end
newImg = TempGradVec(2:end-1,2:end-1);
end
function [num] = isMax(p1,p2,p3)
%if p2 is the biggest
if p2>=p3 && p2>=p1
num=p2;
else
num=0;
end
end

Answers (2)

Image Analyst
Image Analyst on 2 Jun 2012
No - I'm not into reinventing wheels for basic building block functions like this. Any reason why you don't just use the edge() function that's built in to MATLAB's Image Processing Toolbox? It does a Canny filter.
  1 Comment
Steve
Steve on 2 Jun 2012
I need to write it myself as part of some big project.
I know there is such function but I need your professional help to understand what is wrong.
There are a lot of experts here who help a lot including you.

Sign in to comment.


Walter Roberson
Walter Roberson on 3 Jun 2012
Consider your lines
if TempGradVec(i,j) > HiT
TempGradVec(i,j) = 1;
elseif TempGradVec(i,j) < LoT
TempGradVec(i,j) = 0;
Those do convert (some) floating point results to exact 0's and 1's, and store those exact values back into TempGradVec over-top of the previous floating point values. But if the floating point value does not happen to be in that particular range, you go on to the test
elseif TempGradVec(i,j-1) == 1 ||...
TempGradVec(i-1,j) == 1 ||...
TempGradVec(i-1,j+1) == 1 ||...
TempGradVec(i,j-1) == 1 ||...
TempGradVec(i,j+1) == 1 ||...
TempGradVec(i+1,j-1) == 1 ||...
TempGradVec(i+1,j) == 1 ||...
TempGradVec(i+1,j+1) == 1
The first 4 of those tests are looking at locations you have already converted, so it is safe to do exact comparisons to 1 on those locations. But starting from TempGradVec(i,j+1) you are examining a location that you have not already converted and so are looking at raw floating point values. Is it plausible, really, that in those unconverted sections of the matrix, any of the results will exactly equal 1 down to 53 bit binary floating point precision ?

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!