Мне кажется, мне нужно кое-что прояснить в этом коде.
Сначала , предполагается, что обнаруженная область является идеальным квадратом, поскольку игнорирует некоторые точки внутри squares[x]
, чтобы создать новый Mat
.
Секунда , также предполагается, что точки, составляющие область, были обнаружены в направлении по часовой стрелке, начиная с 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 выдает cv::Exception
в вас Mat subimage(image, roi);
.
Что вам нужно сделать, это написать код, который идентифицирует верхнюю левую точку региона и назовет ее p0
, затем ближайший соседний участок справа, p1
, затем найдите нижний правыйукажите точку региона и назовите ее p2
, а затем останется p3
.После этого легко собрать ROI:
Rect roi(p0.x, p0.y,
p1.x - p0.x,
p3.y - p0.y);
EDIT :
Я нашел отличное решение при чтении документации из v2.3 OpenCV.Это автоматизирует процесс, который я описал ранее, и делает вещи намного проще и понятнее.Вы можете использовать этот трюк, чтобы упорядочить 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;
}