为什么OpenCV没有针对区域的专门数据结构? [英] Why OpenCV has no specialize data structure for region?

查看:226
本文介绍了为什么OpenCV没有针对区域的专门数据结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用MVTec的Halcon图像处理库已有半年了,而使用OpenCV已有一年了.

I have been using MVTec's Halcon Image Processing Library for half a year and OpenCV for 1 year.

1.我发现Halcon胜过OpenCV的一件事是OpenCV没有针对区域的专门数据结构.

如果我只想在大空间中存储一个小区域,这将是很多浪费. OpenCV不应为Mat类以外的区域提供一些专门的数据结构.

This is lots of waste if I only want to store a small region in a large space. Shouldn't OpenCV have some specialized data structure for region other than Mat Class.

2.第二个是前一个的结果,它是OpenCV难以遍历区域.

想象一下这样的情况:在执行阈值操作后,我有10个连接的区域块,而我想遍历这10个块来处理每个块.据我所知,我必须首先使用findContours来获取每个区域的所有轮廓,然后使用drawContour来获取该区域.那么我可以说这些区域是由轮廓数据存储的,每次我想取回该区域时都必须调用drawContours吗?

Imagine the scenario that I have 10 connected blocks of region after doing threshold and I want to iterate through that 10 blocks to process each of them. As far as I know, I have to first use findContours to get all the contours of each region and then I use drawContour to get that region. So can I say that the regions is stored by the contour data and each time I want to get the region back I have to call drawContours?

Mat myImage = imread("Path_To_Source_Image");
threshold(myImage, region, 128, 1, THRESH_BINARY);
vector<vector<Point>> contours;
findContours(region, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
for (int i = 0; i < contours.size, i++){
    Mat oneBlock(myImage.size(), CV_8U); 
    drawContours(oneBlock, contours, i, Scalar(255), -1);
        // Now I finally get my region

        //  ***************************************
        //
        //   Do my image procesing for that region
        //
        //  ***************************************
    }

推荐答案

表示区域的一种常见方法是使用包含区域索引的Mat1i(也就是类型为CV_32SMat),即labels.

A common approach to represent regions is to use a Mat1i (aka a Mat of type CV_32S) that contains the indices of the regions, i.e. the labels.

然后您可以使用以下命令轻松访问第i个区域:Mat1b region_mask = (labels == i);

You can then access the i-th region simply with: Mat1b region_mask = (labels == i);

使用OpenCV< 3.0,可以使用findContursdrawContours来创建labels图像:

With OpenCV < 3.0, you can use findConturs and drawContours to create the labels image:

#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;

int main()
{
    // Read image from file 
    Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);

    Mat1b region;
    threshold(img, region, 200, 255, THRESH_BINARY);

    vector<vector<Point>> contours;
    findContours(region.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

    Mat1i labels(img.rows, img.cols, int(0));
    int n_labels = contours.size();

    for (int i = 0; i < contours.size(); ++i)
    {
        drawContours(labels, contours, i, Scalar(i + 1), CV_FILLED); // Note the +1, since 0 is the background
    }

    // Now you can get your regiones as:

    // Label "0" is the background
    for (int i = 1; i <= n_labels; ++i)
    {
        Mat1b region_mask = (labels == i);
        imshow("Region", region_mask);
        waitKey();
    }

    return 0;
}

在OpenCV> = 3.0中,您可以使用connectedComponents,它将直接返回labels:

With OpenCV >= 3.0 you can use connectedComponents, which will directly return the labels:

#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;

int main()
{
    // Read image from file 
    Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);

    Mat1b region;
    threshold(img, region, 200, 255, THRESH_BINARY);

    Mat1i labels;
    int n_labels = connectedComponents(region, labels);

    // Now you can get your regiones as:

    // Label "0" is the background
    for (int i = 1; i <= n_labels; ++i)
    {
        Mat1b region_mask = (labels == i);
        imshow("Region", region_mask);
        waitKey();
    }

    return 0;
}

这篇关于为什么OpenCV没有针对区域的专门数据结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆