[英]OpenCV extract area of an image from a vector of squares
I have an image that contains a square, and I need to extract the area contained in that square. 我有一个包含正方形的图像,我需要提取该正方形中包含的区域。 After applying the squares.c script (available in the samples of every OpenCV distribution) I obtain a vector of squares, then I need to save an image for each of them.
在应用了square.c脚本(在每个OpenCV分布的样本中可用)后,我获得了一个正方形向量,然后我需要为它们中的每个保存一个图像。
The user karlphillip suggested this: 用户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);
}
in order to generate a new Mat called subimage for all the squares detected in the original image 为了在原始图像中检测到的所有方块生成一个称为子图像的新Mat
As karl remembered me, the points detected in the image may not represent a perfect square (as you can see in the image above) but the code I just suggested to you assumes they do. 正如卡尔记得的那样,图像中检测到的点可能并不代表完美的正方形(如上图所示),但我刚给你建议的代码假设它们有。
In fact I get this error: 实际上我收到了这个错误:
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
Suggestion for make the script accept also non perfect squares? 建议使脚本也接受非完美的方块?
I feel like I need to clarify a few things about that code. 我觉得我需要澄清一些有关该代码的内容。
First , it assumes that the region detected is a perfect square because it ignores some of the points inside squares[x]
to create a new Mat
. 首先 ,它假设检测到的区域是一个完美的正方形,因为它忽略了square
squares[x]
内的一些点来创建一个新的Mat
。
Second , it also assumes that the points that make the region were detected in the clockwise direction, starting with p0
in the top-left corner of the image: 其次 ,它还假设以顺时针方向检测到构成该区域的点,从图像左上角的
p0
开始:
(p0) 1st----2nd (p1)
| |
| |
(p3) 4th----3rd (p2)
which might not be true for all the regions detected. 对于检测到的所有区域而言可能并非如此。 That means that this code:
这意味着这段代码:
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);
probably will generate a ROI with invalid dimensions, such as negative width and height values, and that's why OpenCV throws a cv::Exception
at you on Mat subimage(image, roi);
可能会生成一个无效维度的ROI,例如负宽度和高度值,这就是为什么OpenCV会在
Mat subimage(image, roi);
上抛出一个cv::Exception
Mat subimage(image, roi);
. 。
What you should do, is write a code that will identify the top-left point of the region and call it p0
, then it's nearest neightbor on the right side, p1
, then find the bottom-right point of the region and call it p2
, and then what's left is p3
. 您应该做的是编写一个代码,该代码将识别该区域的左上角并将其称为
p0
,然后它在右侧最近的neightbor, p1
,然后找到该区域的右下角并将其称为p2
,然后剩下的是p3
。 After this, assembling the ROI is easy: 在此之后,组装ROI很容易:
Rect roi(p0.x, p0.y,
p1.x - p0.x,
p3.y - p0.y);
EDIT : 编辑 :
I found an excellent solution while reading the documentation of the v2.3 of OpenCV. 在阅读OpenCV v2.3的文档时 ,我找到了一个很好的解决方案 。 It automates the process I described earlier and it make things so much easier and clean.
它使我之前描述的过程自动化,使事情变得如此简单和干净。 You can use this trick to order the 4 Points in the vector to a meaningful
Rect
structure: 您可以使用此技巧将向量中的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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.