2012-08-01 95 views
6

我已执行关闭形态运算和我得到不同的结果与C和C++ API(OpenCV的2.4.2)不同的结果与OPENCV C和C++ API(边界插值差)

输入:

input http://i48.tinypic.com/35jm9n5.png

随着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,但它总是产生相同的结果。

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

+0

可以加入原始图片吗? – 2012-08-03 05:58:24

+0

@HåvardGeithus:输入:http://i47.tinypic.com/9kthzm.png;输入图像是一个Canny边缘输出,如图所示。 – 2012-08-03 10:23:15

回答

5

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

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

2)在'C'中,ROI被视为完全不同的图像。因此,当你执行诸如cvSmooth,cvDilate等的功能时,需要提到边界像素外插方法,'C'API不会将像素的原始图像指向左/右/上/下最大像素以外的像素。它实际上是根据您提到的方法来内插像素值。 3)但是在'C++'中,我发现它总是指向像素的原始图像,超出左/右/上/下最大像素。因此,如果ROI周围的原始图像中有像素,则所提及的边界像素外插方法不会影响您的输出。

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

要声明我的支持,我已经发布了以下的输入/输出图像:

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

输入:

input http://i48.tinypic.com/35jm9n5.png < ---输入

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 http://i45.tinypic.com/345lybm.png < - before_gauss

after_gauss http://i45.tinypic.com/2rg1jm0.png < --- after_gauss

after_canny http://i46.tinypic.com/2ymhyqw.png < --- after_canny

dilate http://i48.tinypic.com/5u4ec1.png < ---扩张

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 http://i45.tinypic.com/345lybm.png < - before_gauss

after_gauss http://i50.tinypic.com/28gxzrb.png

^^^^^ after_gauss(注:边框没有更完全黑色,它们是灰色的)

after_canny http://i45.tinypic.com/2la7ecp.png

^^^^^ after_canny

dilate http://i50.tinypic.com/jhqxbm.png

^^^^^ 扩张

SOLUTION:

创建一个单独的ROI复制和使用进一步分析;

src_ROI.copyTo(new_src_ROI); 

使用new_src_ROI作进一步分析。 如果有人有更好的解决办法,请在

以下发帖
0

由于默认值是不是C和C++之间相同的 - 尤其是结构元素。 在C:默认的结构元素是:

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

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

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

您应指定如果所有字段(包括锚)想要相同的结果。

+0

结构元素也是我的第一个想法。 – 2012-08-02 12:52:51

+0

@ go4sri:这次我将构造元素构建为cv :: getStructuringElement(cv :: MORPH_RECT,cv :: Size(3,3),cv :: Point(1,1));我仍然得到不同的结果:http://i45.tinypic.com/2j4x47q.png;接下来我只试着扩张扩张结果:http://i48.tinypic.com/10o20ky.png;正如你所看到的,四面八方都有白色边框。这不应该是这样吗?我尝试改变边界类型,但它总是产生相同的结果 – 2012-08-02 21:49:34

+0

@HåvardGeithus:形态学结束:cv :: morphologyEx(src,src,cv :: MORPH_CLOSE,structuringElement,cv :: Point(1,1),5); – 2012-08-02 21:50:54

0

从OpenCV v2.4.2文档检出此sample code。您可能还想检查使用Canny边缘检测器的this code。这些将有望帮助您追踪错误:)

还要注意形态闭合是一个幂等运算符,所以它可以多次应用而不会改变超出初始应用程序的结果。