I have performed Closing morphological operation and I am getting different result with the C and C++ API (OpenCV 2.4.2)
Input:
With OpenCV 'C':
//Set ROI
//Perform Gaussian smoothing
//Perform Canny edge analysis
cvMorphologyEx( src, dst, temp, Mat(), MORPH_CLOSE, 5 );
RESULT: http://i47.tinypic.com/33e0yfb.png
With Opencv C++
//Set ROI
//Perform Gaussian smoothing
//Perform Canny edge analysis
cv::morphologyEx( src, dst, cv::MORPH_CLOSE, cv::Mat(), cv::Point(-1,-1), 5 );
RESULT: http://i50.tinypic.com/i5vxjo.png
As you can see, the C++ API yields an output with White/Gray border color. Hence, the results are different for both of these APIs.
I have tried different borderType with the C++ API but it always yields the same result.
How can I get the same output as C API in C++? I need it because it affects the detected contours
Thanks in advance
Thank you everybody for answering this question. I have found my error. I am going to describe it in brief below. Hope it helps others facing this problem.
1) I had executed the C and C++ commands on a ROI image. Apparently, the way OpenCV 'C' and 'C++' API treat ROI is different.
2) In 'C', a ROI is treated as a completely different image. Hence, when you execute functions such as cvSmooth, cvDilate, etc, where one needs to mentions border Pixel extrapolation methods, the 'C' API does not refer back to the original image for pixels beyond left/right/top/bottom most pixel. It actually interpolates the pixel values according to the method you mentioned.
3) But in 'C++', I have found that it always refers back to the original image for pixels beyond left/right/top/bottom most pixel. Hence, the border pixel extrapolation method mentioned doesn't affect your output if there are pixels in the original image around your ROI.
I think it applies the order pixel extrapolation method to the original image instead of the ROI unlike the 'C' API. I don't know if this a bug; I haven't completely read the OpenCV 2.4.2 C++ API documentation. (Please correct me if I am wrong)
To claim my support, I have posted input/output images below:
Output for 'C' and C++ API:
INPUT:
<--- input
OpenCV 'C' API:
IplImage *src = cvLoadImage("input.png", 0);
cvSetImageROI( src, cvRect(33,19,250,110));
cvSaveImage( "before_gauss.png", src );
cvSmooth( src, src, CV_GAUSSIAN );
cvSaveImage("after_gauss.png", src);
IplConvKernel *element = cvCreateStructuringElementEx(3,3,1,1,CV_SHAPE_RECT);
cvCanny( src, src, 140, 40 );
cvSaveImage("after_canny.png", src);
cvDilate( src, src, element, 5);
cvSaveImage("dilate.png", src);
OUTPUT:
<-- before_gauss
<--- after_gauss
<--- after_canny
<--- dilate
OpenCV 'C++' API:
cv::Mat src = cv::imread("input.png", 0);
cv::Mat src_ROI = src( cv::Rect(33,19,250,110));
cv::imwrite( "before_gauss.png", src_ROI );
cv::GaussianBlur( src_ROI, src_ROI, cv::Size(3,3),0 );
cv::imwrite( "after_gauss.png", src_ROI );
cv::Mat element = cv::getStructuringElement( cv::MORPH_RECT, cv::Size(3, 3), cv::Point(1,1));
cv::Canny( src_ROI, src_ROI, 140, 40);
cv::imwrite( "after_canny.png", src_ROI );
cv::dilate( src_ROI, src_ROI, element, cv::Point(1,1), 5);
cv::imwrite( "dilate.png", src_ROI );
OUTPUT:
<-- before_gauss
^^^^^ after_gauss (NOTE: the borders are no more completely black, they are grayish)
^^^^^ after_canny
^^^^^ dilate
SOLUTION:
Create a separate ROI copy and use it for further analysis;
src_ROI.copyTo( new_src_ROI );
Use new_src_ROI for further analysis. If anyone has better solution, please post below
The defaults are not the same between C and C++ - especially the structuring element. In C: the default structuring element is:
cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_RECT)
whereas in C++, the default structuring element is:
getStructuringElement(MORPH_RECT, Size(1+iterations*2,1+iterations*2));
You should specify all fields(including the anchor) if you want the same results.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With