Different results with OPENCV C and C ++ API (difference between border interpolation)

I performed a morphological closure operation and get a different result using the C and C ++ APIs (OpenCV 2.4.2)

Entrance:

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 gives output with white / gray border color. Consequently, the results are different for both of these APIs.

I tried a different type of borderType with the C ++ API, but it always gives the same result.

How can I get the same output as the C API in C ++? I need it because it affects the detected loops

thanks in advance

+6
source share
3 answers

Thanks to everyone for answering this question. I found my mistake. I am going to describe it briefly below. Hope this helps others facing this issue.

1) I executed the C and C ++ commands for the ROI image. Obviously, the OpenCV 'C' and 'C ++' methods handle ROI in different ways.

2) In "C", the ROI is considered as a completely different image. Therefore, when you perform functions such as cvSmooth, cvDlate, etc., Where you need to mention the methods of extrapolating pixels at the border, the "C" API does not refer to the original image for pixels that go beyond the left / right / top / bottom most pixels. In fact, it interpolates the pixel values ​​according to the method you mentioned.

3) But in 'C ++', I found that it always refers to the original image for the pixels behind the left / right / top / bottom most pixels. Therefore, the mentioned method of extrapolating boundary pixels does not affect your output if there are pixels around your area of ​​interest in the original image.

I think that it applies the method of extrapolating order pixels to the original image instead of ROI, unlike API C. I do not know if this is an error; I have not fully read the OpenCV 2.4.2 C ++ API documentation. (Please correct me if I am wrong)

To get support, I posted the I / O images below:

Output for API C and C ++:

ENTRANCE:

input & lt; --- 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); 

CONCLUSION:

before_gauss & lt; - before_gauss

after_gauss & lt; --- after_gauss

after_canny & lt; --- after_canny

dilate & lt; --- expand

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 ); 

CONCLUSION:

before_gauss & lt; - before_gauss

after_gauss

^^^^^ after_gauss (NOTE: the borders are no longer completely black, they are grayish)

after_canny

^^^^^ after_canny

dilate

^^^^^ expand

DECISION:

Create a separate copy of the ROI and use it for further analysis;

 src_ROI.copyTo( new_src_ROI ); 

Use new_src_ROI for further analysis. If anyone has a better solution, please write below

+5
source

The default values ​​do not match between C and C ++, especially the structuring element. In C: default structuring element:

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 must specify all fields (including the anchor) if you want to get the same results.

0
source

Check out this sample code from the OpenCV v2.4.2 documentation. You can also check this code to use the Canny edge detector. They hopefully help you track the bug :)

Also note that morphological closure is an idempotent operator, so it can be applied several times without changing the result outside the original application.

0
source

Source: https://habr.com/ru/post/921897/


All Articles