Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenCV从正方形矢量中提取图像的面积_C++_Opencv_Image Processing_Object Detection_Roi - Fatal编程技术网

C++ OpenCV从正方形矢量中提取图像的面积

C++ OpenCV从正方形矢量中提取图像的面积,c++,opencv,image-processing,object-detection,roi,C++,Opencv,Image Processing,Object Detection,Roi,我有一个包含正方形的图像,我需要提取该正方形中包含的区域。 应用squares.c脚本(可在每个OpenCV分布的样本中获得)后,我获得了一个正方形向量,然后需要为每个正方形保存一个图像 用户karlphillip建议: for (size_t x = 0; x < squares.size(); x++) { Rect roi(squares[x][0].x, squares[x][0].y, squares[x][1].x - squares[x]

我有一个包含正方形的图像,我需要提取该正方形中包含的区域。 应用squares.c脚本(可在每个OpenCV分布的样本中获得)后,我获得了一个正方形向量,然后需要为每个正方形保存一个图像

用户karlphillip建议:

for (size_t x = 0; x < squares.size(); x++) 
{
    Rect roi(squares[x][0].x, squares[x][0].y, 
             squares[x][1].x - squares[x][0].x, 
             squares[x][3].y - squares[x][0].y);
    Mat subimage(image, roi);
}
(大小x=0;x { 矩形roi(正方形[x][0]。x,正方形[x][0]。y, 正方形[x][1].x-正方形[x][0].x, 正方形[x][3].y-正方形[x][0].y); Mat子图像(图像,roi); } 为了为原始图像中检测到的所有正方形生成一个称为子图像的新Mat

正如karl记得的那样,图像中检测到的点可能并不代表一个完美的正方形(如上图所示),但我刚才向您建议的代码假设它们是

事实上,我得到了这个错误:

OpenCV Error: Assertion failed (0 <= roi.x && 0 <= roi.width &&
      roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height &&
      roi.y + roi.height <= m.rows) in Mat, file /usr/include/opencv/cxmat.hpp, 
      line 187

terminate called after throwing an instance of 'cv::Exception'
what():  /usr/include/opencv/cxmat.hpp:187: error: (-215) 0 <= roi.x && 
       0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y &&
       0 <= roi.height && roi.y + roi.height <= m.rows in function Mat

Aborted

OpenCV错误:断言失败(0我觉得我需要澄清关于该代码的一些事情

首先,它假设检测到的区域是一个完美的正方形,因为它忽略了
正方形[x]
内的一些点来创建一个新的
Mat

Second,它还假设在顺时针方向检测到构成该区域的点,从图像左上角的
p0
开始:

(p0)  1st----2nd  (p1)
       |      |
       |      |
(p3)  4th----3rd  (p2)
对于检测到的所有区域,这可能不是真的。这意味着此代码:

Rect roi(squares[x][0].x, squares[x][0].y, 
         squares[x][1].x - squares[x][0].x, 
         squares[x][3].y - squares[x][0].y);
可能会生成具有无效维度的ROI,例如负宽度和高度值,这就是OpenCV在
Mat子图像(图像,ROI);
上向您抛出
cv::Exception
的原因

您应该做的是,编写一个代码,识别区域的左上角点,并将其称为
p0
,然后它是右侧最近的邻居,
p1
,然后找到区域的右下角点并将其称为
p2
,然后剩下的是
p3
。在此之后,组装ROI很容易:

Rect roi(p0.x, p0.y, 
         p1.x - p0.x, 
         p3.y - p0.y);
编辑

我在阅读OpenCV的v2.3版本时发现了一个非常好的解决方案。它自动化了我前面描述的过程,使事情变得更加简单和干净。您可以使用此技巧将向量中的4个点排序为有意义的
Rect
结构:

// Data returned and filled by findSquares(). Check the example squares.cpp for more info on this function.
vector<vector<Point> > squares;

for (size_t i = 0; i < squares.size(); i++)
{
    Rect rectangle = boundingRect(Mat(squares[i]));
    cout << "#" << i << " rectangle x:" << rectangle.x << " y:" << rectangle.y << " " << rectangle.width << "x" << rectangle.height << endl;
}
//findSquares()返回并填充的数据。有关此函数的详细信息,请查看示例squares.cpp。
矢量平方;
对于(size_t i=0;i虽然这个技巧对该示例图像()非常有效,但如果我尝试使用不同的图像(例如,但在许多其他输入图像中也会出现这种情况),我会继续收到相同的异常…此外,对于其他图像(),我得到:
libpng警告:IHDR libpng中的图像宽度为零错误:无效IHDR数据OpenCV错误:错误标志cvGetMat中的(参数或结构字段)(无法识别或不支持的数组类型)错误:(-206)函数cvGetMat中无法识别或不支持的数组类型
导致问题的行是
Mat子图像(图像,roi);
,问题是检测到的正方形的尺寸(aka.
roi
)似乎不对。您需要将这些坐标打印到屏幕上,看看它们是否真的有意义,因为OpenCV认为它们没有意义。您还应该打印X的所有值,并查看所有正方形检测到的所有坐标。可能在检测过程中发生了奇怪的事情,您正在查看一个孤立的案例。无论如何,我在回答中解释的是正确的,从现在起,这取决于你和你的调试技巧。@Marco顺便说一句,我刚刚用代码更新了答案,这将为你省去很多麻烦。它自动识别点的过程,并将它们组织成一个Rect结构。这在OpenCV 2.3的文档中找到。这就是我有更多的理由停止使用他们提供的在线文档(用于v2.1),并开始使用OpenCV 2.3.x附带的文档。我想现在你可以接受我的正式答案了。