为什么OpenCV没有针对区域的专门数据结构? [英] Why OpenCV has no specialize data structure for region?
问题描述
我已经使用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_32S
的Mat
),即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,可以使用findConturs
和drawContours
来创建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屋!