谢谢大家回答这个问题。我发现了我的错误。我将在下面简要描述它。希望它可以帮助其他人面临这个问题。
1) 我在 ROI 图像上执行了 C 和 C++ 命令。显然,OpenCV 'C' 和 'C++' API 处理 ROI 的方式是不同的。
2) 在“C”中,ROI 被视为完全不同的图像。因此,当您执行 cvSmooth、cvDilate 等需要提及边界像素外推方法的函数时,“C”API 不会针对超出最左/右/顶部/底部像素的像素返回原始图像。它实际上是根据您提到的方法对像素值进行插值。
3)但在'C++'中,我发现它总是引用原始图像的像素超出左/右/顶部/底部最像素。因此,如果您的 ROI 周围的原始图像中有像素,则提到的边界像素外推方法不会影响您的输出。
我认为它将顺序像素外推方法应用于原始图像而不是 ROI,这与“C”API 不同。我不知道这是否是一个错误;我还没有完全阅读 OpenCV 2.4.2 C++ API 文档。(如果我错了请纠正我)
为了获得我的支持,我在下面发布了输入/输出图像:
'C' 和 C++ API 的输出:
输入:
<--- 输入
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);
输出:
<-- before_gauss
<--- after_gauss
<--- 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 );
输出:
<-- before_gauss
^^^^^ after_gauss(注意:边框不再完全是黑色的,它们是灰色的)
^^^^^ after_canny
^^^^^扩张
解决方案:
创建单独的 ROI 副本并将其用于进一步分析;
src_ROI.copyTo( new_src_ROI );
使用 new_src_ROI 进行进一步分析。如果有人有更好的解决方案,请在下面发布