首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用OpenCV,尝试提取由ArrayOfArrays描述的图片的区域

使用OpenCV,尝试提取由ArrayOfArrays描述的图片的区域
EN

Stack Overflow用户
提问于 2012-04-16 22:36:23
回答 3查看 24.7K关注 0票数 10

我正在用iOS开发一些图像处理工具。目前,我有一个计算的特征轮廓,它的类型是InputArrayOfArrays。

声明为:

代码语言:javascript
复制
std::vector<std::vector<cv::Point> > contours_final( temp_contours.size() );

现在,我想提取原始RGB图片中由轮廓线圈出的区域,并进一步将子图像存储为cv::Mat格式。我该怎么做呢?

提前感谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-04-17 14:54:35

我猜你想要做的就是提取检测到的轮廓中的区域。以下是一种可能的解决方案:

代码语言:javascript
复制
using namespace cv;

int main(void)
{
    vector<Mat> subregions;
    // contours_final is as given above in your code
    for (int i = 0; i < contours_final.size(); i++)
    {
        // Get bounding box for contour
        Rect roi = boundingRect(contours_final[i]); // This is a OpenCV function

        // Create a mask for each contour to mask out that region from image.
        Mat mask = Mat::zeros(image.size(), CV_8UC1);
        drawContours(mask, contours_final, i, Scalar(255), CV_FILLED); // This is a OpenCV function

        // At this point, mask has value of 255 for pixels within the contour and value of 0 for those not in contour.

        // Extract region using mask for region
        Mat contourRegion;
        Mat imageROI;
        image.copyTo(imageROI, mask); // 'image' is the image you used to compute the contours.
        contourRegion = imageROI(roi);
        // Mat maskROI = mask(roi); // Save this if you want a mask for pixels within the contour in contourRegion. 

        // Store contourRegion. contourRegion is a rectangular image the size of the bounding rect for the contour 
        // BUT only pixels within the contour is visible. All other pixels are set to (0,0,0).
        subregions.push_back(contourRegion);
    }

    return 0;
}

如果要将子区域存储为支持透明度的格式(如png),您可能还需要考虑保存各个蒙版,以便有选择地用作alpha通道。

注意:我没有提取每个轮廓边界框中的所有像素,只是提取轮廓内的像素。不在轮廓内但在边界框内的像素被设置为0。原因是您的Mat对象是一个数组,这使它成为矩形。

最后,我看不出您有任何理由只将轮廓中的像素保存在一个专门创建的数据结构中,因为您需要存储每个像素的位置才能重新创建图像。如果你关心的是节省空间,这根本不会节省你太多的空间。保存最紧的边界框就足够了。如果您只想分析轮廓区域中的像素,则为每个轮廓保存蒙版的副本,以便您可以使用它来检查轮廓中的哪些像素。

票数 25
EN

Stack Overflow用户

发布于 2012-04-16 22:48:53

您正在寻找连接这些点的cv::approxPolyDP()函数。

我在this post中分享了整个过程的类似用法。在findContours()调用之后检查for循环。

票数 0
EN

Stack Overflow用户

发布于 2012-04-17 14:32:12

我想你要找的是cv::boundingRect()。如下所示:

代码语言:javascript
复制
using namespace cv;
Mat img = ...;
...
vector<Mat> roiVector;
for(vector<vector<Point> >::iterator it=contours.begin(); it<contours.end(); it++) {
    if (boundingRect( (*it)).area()>minArea) {
        roiVector.push_back(img(boundingRect(*it)));
    }
}

cv::boundingRect()接受一个点的向量,并返回一个cv::Rect。初始化一个Mat myRoi = img(myRect)会给出一个指向该图像部分的指针(因此修改myRoi也会修改img)。

请参阅更多here

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10176184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档