Why is the edge detection in MATLAB different to OpenCV or custom code write by algorithm?

14 views (last 30 days)
When I am comparing the outputs of using the "edge" function in MATLAB to the "edge" function in OpenCV, or if i write code for some edge detector (sobel, canny, robets), expecily for Roberts operator, there is a big differences.
Why is that?
  1 Comment
dpb
dpb on 9 Mar 2020
And why shouldn't it be? For a detailed explanation of at least some of the differences on a particular implementation, see <Canny-edge-detection-in-matlab-different-to-opencv?>
Undoubtedly, if the source is available for the others (I don't have the TB so can't go look) you could do a comparative analysis of the others (or, you might get lucky and perhaps TMW may have sprinkled some comments thru the code for you). But, ML is a proprietary product; they can choose the implementation as they see fit without being beholden to any outside choice.

Sign in to comment.

Answers (2)

Steven Lord
Steven Lord on 9 Mar 2020
Different doesn't necessarily mean wrong. If you have an example where you believe the edge function is returning incorrect results (not just different results) please send the example to Technical Support for investigation.
I haven't read the source code for the edge function but some potential causes of differences include:
  • Different values for parameters in the algorithm (tolerances, particularly)
  • Ambigous situations (if you try to triangulate the unit square, do you cut it from the upper-left to lower-right or upper-right to lower-left? Both are valid triangulations of the square.)
  • Different but similarly named options (for example, what if a statistical function in one software package were to require the standard deviation of a set of data as input but that same function in another requires the variance instead?)
  7 Comments
dpb
dpb on 9 Mar 2020
Use the Code button to attach code in the forum...not likely anybody is going offsite.
"Help us help you!"
dpb
dpb on 9 Mar 2020
You are right.
Here is code in matlab:
close all;
clear all;
clc
i = imread(yourPath);
image = i;
%image=rgb2gray(i);
%Custome Sobel%%%%%%%%%%%%%%%%
%B=image;
%C=double(B);
%for i=1:size(C,1)-2
% for j=1:size(C,2)-2
%Sobel mask for x-direction:
% Gx=((2*C(i+2,j+1)+C(i+2,j)+C(i+2,j+2))-(2*C(i,j+1)+C(i,j)+C(i,j+2)));
%Sobel mask for y-direction:
% Gy=((2*C(i+1,j+2)+C(i,j+2)+C(i+2,j+2))-(2*C(i+1,j)+C(i,j)+C(i+2,j)));
%The gradient of the image
%B(i,j)=abs(Gx)+abs(Gy);
% B(i,j)=sqrt(Gx.^2+Gy.^2);
% end
%end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
BW=edge(image,'sobel'); %Find edges in intensity image,returns a binary image BW containing
%1s where the function finds edges in the input image I and 0s elsewhere. By default, edge uses
%the Sobel edge detection method.
J = stdfilt(BW) ;%computer standard deviation across each sobel filtered frame
ts = timeseries((J'));%creates the time-series object using the specified data.
SI = max(ts);%compute maximum data sample
fprintf('\n SI_std: %0.2f', std(SI));
fprintf('\n SI_mean: %0.2f', mean(SI));
Here is code in Python:
image = Image.open(path)
## Applying vertical and horizontal Sobel filter
print('Applying vertical and horizontal Sobel filter')
dy = ndimage.filters.sobel( image , 1 )
dx = ndimage.filters.sobel( image , 0 )
## Calculate the map of the spatial information (SI) or,
## in other words, the map of magnitudes of the edge images
npix = image.shape[0] * image.shape[1]
map_si = np.sqrt(dx*dx + dy*dy)
si_mean = np.mean( map_si )
si_rms = np.sqrt( 1.0/npix * np.sum( map_si * map_si ) )
si_std = np.std( map_si )
print('\nSI -- mean: ', si_mean )
print('SI -- rms: ', si_rms )
print('SI -- std: ', si_std )
So, its made by formula:
SI_p = sqrt(gh^2 + gv^2)
where gh and gv are horizontal and vertical gradients (calculated with sobel masks).
SI_mean = (1/P)*sum(SI_p )
SI_std = sqrt((1/P)*sum(SI_p - SI_mean)^2)
SI = max_time {SI_std}

Sign in to comment.


mavicV
mavicV on 9 Mar 2020
Edited: dpb on 9 Mar 2020
[Moved Vladimir Answer to Comment -- Note to VM -- why don't you edit this into your original Q? It's what folks need to see to be able to answer. --dpb]
You are right.
Here is code in matlab:
close all;
clear all;
clc
i = imread(yourPath);
image = i;
%image=rgb2gray(i);
%Custome Sobel%%%%%%%%%%%%%%%%
%B=image;
%C=double(B);
%for i=1:size(C,1)-2
% for j=1:size(C,2)-2
%Sobel mask for x-direction:
% Gx=((2*C(i+2,j+1)+C(i+2,j)+C(i+2,j+2))-(2*C(i,j+1)+C(i,j)+C(i,j+2)));
%Sobel mask for y-direction:
% Gy=((2*C(i+1,j+2)+C(i,j+2)+C(i+2,j+2))-(2*C(i+1,j)+C(i,j)+C(i+2,j)));
%The gradient of the image
%B(i,j)=abs(Gx)+abs(Gy);
% B(i,j)=sqrt(Gx.^2+Gy.^2);
% end
%end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
BW=edge(image,'sobel'); %Find edges in intensity image,returns a binary image BW containing
%1s where the function finds edges in the input image I and 0s elsewhere. By default, edge uses
%the Sobel edge detection method.
J = stdfilt(BW) ;%computer standard deviation across each sobel filtered frame
ts = timeseries((J'));%creates the time-series object using the specified data.
SI = max(ts);%compute maximum data sample
fprintf('\n SI_std: %0.2f', std(SI));
fprintf('\n SI_mean: %0.2f', mean(SI));
Here is code in Python:
image = Image.open(path)
## Applying vertical and horizontal Sobel filter
print('Applying vertical and horizontal Sobel filter')
dy = ndimage.filters.sobel( image , 1 )
dx = ndimage.filters.sobel( image , 0 )
## Calculate the map of the spatial information (SI) or,
## in other words, the map of magnitudes of the edge images
npix = image.shape[0] * image.shape[1]
map_si = np.sqrt(dx*dx + dy*dy)
si_mean = np.mean( map_si )
si_rms = np.sqrt( 1.0/npix * np.sum( map_si * map_si ) )
si_std = np.std( map_si )
print('\nSI -- mean: ', si_mean )
print('SI -- rms: ', si_rms )
print('SI -- std: ', si_std )
So, its made by formula:
SI_p = sqrt(gh^2 + gv^2)
where gh and gv are horizontal and vertical gradients (calculated with sobel masks).
SI_mean = (1/P)*sum(SI_p )
SI_std = sqrt((1/P)*sum(SI_p - SI_mean)^2)
SI = max_time {SI_std}
  2 Comments
dpb
dpb on 9 Mar 2020
Edited: dpb on 9 Mar 2020
Well, it's the same thing been saying all along -- you have each language use its own internal implementation of the edge detection algorithm of a nominal name/type of algorithm, but there's absolutely no reason and should be no expectation that the two languages will have actually implemented the basic idea in the identical fashion.
You would have to look at the details internally of the two to have a precise explanation of what is actually different but it's the same kind of thing as TMW Staff outlined for Canny for any of the others.
While you have computed something later with the results, the starting inputs at that point aren't the same, hence the outputs aren't the same.
If you take the output of one and do the mean, variance calculation that did on the other, then you should indeed, get same result(*). But, you're starting with different inputs.
(*) This presumes of course that the ML function stdfilt does identically what your Python calculation does, of course. I don't have the toolbox so can't verify that to be so without more effort than have time to give at moment.

Sign in to comment.

Categories

Find more on Read, Write, and Modify Image in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!