基于Canny边缘轮廓处理所得到的源图像,使用OpenCV进行源图像分割。

3
我有一张源图像。我需要从中分割出特定部分并将其保存为另一张图像。我已经得到了需要分割的部分的Canny轮廓,但是如何使用它从源图像中切割出该部分呢?我已经附上了源图像和Canny边缘轮廓。请帮助我并提供解决方案。

Source Image

Canny edge

编辑-1:Alexander Kondratskiy,这是您所说的填充边界吗?在此输入图片描述

编辑-2:根据Kannat的说法,我已经完成了这个操作具有轮廓的源图像

现在我该如何将轮廓内外的区域分成两个独立的图像?

编辑3- 我想到了“与运算”掩模和轮廓线源图像。由于我正在使用C语言,所以遇到了一些困难。这是我用来进行与运算的代码:

            hsv_gray = cvCreateImage( cvSize(seg->width, seg->height), IPL_DEPTH_8U, 1 );                       
                    cvCvtColor( seg, hsv_gray, CV_BGR2GRAY );                       
                    hsv_mask=cvCloneImage(hsv_gray);
            IplImage* contourImg =cvCreateImage( cvSize(hsv_mask->width, hsv_mask->height), IPL_DEPTH_8U, 3 );                      
            IplImage* newImg=cvCreateImage( cvSize(hsv_mask->width, hsv_mask->height), IPL_DEPTH_8U, 3 );
            cvAnd(contourImg, hsv_mask,newImg,NULL);

我总是遇到大小或类型不匹配的错误。我调整了大小,但似乎无法调整类型,因为一个(hsv_mask)是1通道,而其他通道是3个。

@kanat- 我也尝试了你的boundingrect,但似乎无法以C格式正确使用。


使用带有掩码的copyTo函数。 - Miki
2个回答

0

使用cv::findContours函数在第二张图像上找到该段的轮廓。然后使用cv::boundingRect函数找到该段的边界框。之后,您可以创建矩阵并将其保存在从第二个图像裁剪的边界框中(我看到它是二进制图像)。要裁剪所需区域,请使用以下代码:

cv::getRectSubPix(your_image, BB_size, cv::Point(BB.x + BB.width/2, BB.y + BB.height/2), new_image)。 然后,您可以使用cv::imwrite保存new_image。就这样。

编辑:

如果您只找到一个轮廓,则使用以下代码(否则,您将遍历找到的轮廓元素)。以下代码显示了步骤,但很抱歉我现在无法测试它:

std::vector<std::vector<cv::Point>> contours;
// cv::findContours(..., contours, ...);
cv::Rect BB = cv::boundingRect(cv::Mat(contours[0]));
cv::Mat new_image;
cv::getRectSubPix(your_image, BB.size(), cv::Point(BB.x + BB.width/2, 
BB.y + BB.height/2), new_image);
cv::imwrite("new_image_name.jpg", new_image);

Kanat,我已经完成了轮廓部分,但是在编写boundingRect部分时遇到了问题... - Abhishek V. Pai
@AbhishekV.Pai,抱歉回复晚了,我已经编辑了答案。 - Kanat
@kanat- 如果我将其与填充掩码“and”起来呢? - Abhishek V. Pai
@AbhishekV.Pai,看来我误解了问题。是的,使用“and”可以正常工作。 - Kanat
@kanat- 不想显得太需要,但你能帮我吗?我需要C语言的代码,不是C++。我已经尝试过了,但一直出现错误。 - Abhishek V. Pai
@AbhishekV.Pai,在您编辑的代码中,您在cvAnd中使用的两个图像中的通道数分别为3和1。这会导致错误。忘记boundingRect吧,它不是合适的解决方案。您可以使用cvAnd(original_image, filled_image, new_image)。如果填充图像与原始图像具有不同的图像类型,请使用cvCvtColor将其转换为相同的类型。然后就可以使用cvAnd(original_image, converted_image, new_image)了。 - Kanat

0

您可以填充由Canny边缘检测器创建的边界,并将其用作原始图像上的Alpha掩码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接