Reputation: 393
I'm new to OpenCV and trying to convert the following MATLAB code to OpenCV using C++:
[FX,FY]=gradient(mycell{index});
I have tried the following so far but my values are completely different from my MATLAB results
Mat abs_FXR;
Mat abs_FYR;
int scale = 1;
int delta = 0;
// Gradient X
Sobel(myImg, FXR, CV_64F, 1, 0, 3, scale, delta, BORDER_DEFAULT);
convertScaleAbs( FXR, abs_FXR );
imshow( window_name2, abs_FXR );
// Gradient Y
Sobel(myImg, FYR, CV_64F, 0, 1, 3, scale, delta, BORDER_DEFAULT);
convertScaleAbs( FYR, abs_FYR );
imshow( window_name3, abs_FYR );
I also tried using filter2D as per this question, but it still gave different results: Matlab gradient equivalent in opencv
Mat kernelx = (Mat_<float>(1,3)<<-0.5, 0, 0.5);
Mat kernely = (Mat_<float>(3,1)<<-0.5, 0, 0.5);
filter2D(myImg, FXR, -1, kernelx);
filter2D(myImg, FYR, -1, kernely);
imshow( window_name2, FXR );
imshow( window_name3, FYR );
I don't know if this is way off track or if it's just a parameter I need to change. Any help would be appreciated.
UPDATE Here is my expected output from MATLAB:
But here is what I'm getting from OpenCV using Sobel:
And here is my output from OpenCV using the Filter2D method (I have tried increasing the size of my gaussian filter but still get different results compared to MATLAB)
I have also converted my image to double precision using:
eye_rtp.convertTo(eye_rt,CV_64F);
Upvotes: 1
Views: 2914
Reputation: 30579
It is correct that you need to do a central difference computation instead of using the Sobel filter (although Sobel does give a nice derivative) in order to match gradient
. BTW, if you have the Image Processing Toolbox, imgradient
and imgradientxy
have the option of using Sobel to compute the gradient. (Note that the answer in the question you referenced is wrong that Sobel only provides a second derivative, as there are first and second order Sobel operators available).
Regarding the differences you are seeing, you may need to convert myImg
to float or double before filter2D
. Check the output type of FXL
, etc.
Also, double precision is CV_64F
and single precision is CV_32F
, although this will probably only cause very small differences in this case.
Upvotes: 2