繁体   English   中英

与OPENCV C和C ++ API不同的结果(边界插值差异)

[英]Different result with OPENCV C and C++ API (Border Interpolation difference)

我已经执行了Closing形态学操作,我得到了与C和C ++ API不同的结果(OpenCV 2.4.2)

输入:

输入

使用OpenCV'C':

//Set ROI
//Perform Gaussian smoothing
//Perform Canny edge analysis
cvMorphologyEx( src, dst, temp, Mat(), MORPH_CLOSE, 5 );

结果: http//i47.tinypic.com/33e0yfb.png

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

结果: http//i50.tinypic.com/i5vxjo.png

如您所见,C ++ API产生具有白色/灰色边框颜色的输出。 因此,这两种API的结果都不同。

我已尝试使用C ++ API使用不同的borderType,但它总是产生相同的结果。

如何在C ++中获得与C API相同的输出? 我需要它,因为它会影响检测到的轮廓

提前致谢

谢谢大家回答这个问题。 我发现了我的错误。 我将在下面简要介绍它。 希望它能帮助其他人面对这个问题。

1)我在ROI图像上执行了C和C ++命令。 显然,OpenCV'C'和'C ++'API处理ROI的方式是不同的。

2)在'C'中,ROI被视为完全不同的图像。 因此,当您执行cvSmooth,cvDilate等函数时,需要提及边界Pixel外推方法时,'C'API不会返回原始图像,以查看超出左/右/上/下最像素的像素。 它实际上是根据您提到的方法插值像素值。

3)但是在'C ++'中,我发现它总是返回原始图像,用于超出左/右/上/下最像素的像素。 因此,如果ROI周围的原始图像中有像素,则提到的边框像素外推方法不会影响输出。

我认为与'C'API不同,它将顺序像素外推方法应用于原始图像而不是ROI。 我不知道这是不是一个错误; 我还没有完全阅读OpenCV 2.4.2 C ++ API文档。 (如果我错了,请纠正我)

为了获得我的支持,我在下面发布了输入/输出图像:

'C'和C ++ API的输出:

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 < - before_gauss

after_gauss <--- after_gauss

after_canny <--- after_canny

膨胀 <---扩张

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 < - before_gauss

after_gauss

^^^^^ after_gauss (注意:边框不再是完全黑色,它们是灰色的)

after_canny

^^^^^ after_canny

膨胀

^^^^^ 扩张

解:

创建单独的ROI副本并将其用于进一步分析;

src_ROI.copyTo( new_src_ROI ); 

使用new_src_ROI进行进一步分析。 如果有人有更好的解决方案,请在下面发布

C和C ++之间的默认值不一样 - 尤其是结构元素。 在C中:默认的结构元素是:

cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_RECT)

而在C ++中,默认的结构元素是:

getStructuringElement(MORPH_RECT, Size(1+iterations*2,1+iterations*2));

如果需要相同的结果,则应指定所有字段(包括锚点)。

查看OpenCV v2.4.2文档中的示例代码 您可能还需要检查此代码以使用Canny边缘检测器。 这些将有助于您追踪错误:)

另请注意,形态闭合是幂等运算符,因此可以多次应用它而不会将结果更改为初始应用程序之外的结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM