这不是你问题的答案,只是一个建议。
在我看来,角点检测器并不是检测矩形的好方法 - 如mathematician1975所建议的那样,计算所有点之间的距离需要很长时间。在这种情况下,你必须使用另一种技术:
更新:
以下是另一种在灰度图像中也应适用的解决方案。
ContourArea / BoundingReactangleArea > constant
我将这个constant
视为0.9。
这个算法给了我下面的结果:
以下是OpenCV代码:
Mat src = imread("input.jpg"), gray, result;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
result = Mat(src.size(), CV_8UC1);
cvtColor(src, src, CV_BGR2GRAY);
threshold(src, gray, 200, 255, THRESH_BINARY_INV);
findContours(gray, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
result = Scalar::all(0);
for (size_t i=0; i<contours.size(); i++)
{
Rect rect = boundingRect(contours[i]);
if (rect.area() > 1000)
{
double area = contourArea(contours[i]);
if (area/rect.area() > 0.9)
{
drawContours(result, contours, i, Scalar(255), -1);
}
}
}
计算在4个不同点之间,每一对点之间将会有6种长度。如果这6种长度中有超过3个不同的值,则说明你没有一个矩形(2条相等的边长以及相等的对角线长度)。
方法1
,平行检查为方法2
。那么:%# method 1:
n1 = |u1-u2| %# 3 sub., 3 mult, 2 add. per distance
n2 = |u3-u2| %# total of 6 distances to compute.
n3 = |u4-u3| %# then max 5+4+3+2+1 = 15 comp. to find unique distances
n4 = |u1-u4|
n5 = |u4-u2| %# Total:
n6 = |u3-u1| %# 12 sub., 18 mult., 12 add, 15 comp
%# method 2:
w1 = u1-u2 %# 3 subtractions per vector
w2 = u3-u2 %# total of 4 vectors to compute
w3 = u3-u2
w4 = u1-u4
%# 12 sub.
abs(w1-w3) == [0 0 0] %# 3 sub., 3 comp., 1 sign.
abs(w2-w4) == [0 0 0] %# 3 sub., 3 comp., 1 sign.
%# Total: 18 sub., 6 comp. 2 sign.
方法2
需要事先知道顶点已经按正确顺序排列。如果不是这种情况,它将使成本增加4倍,而这比方法1
更多。distance = sqrt( (x2-x1)^2 + (y2-y1)^2 );
我不确定它是否是2500x4,因为你必须选择一个点,然后再选择另外3个点,计算距离,然后对于相同的第一个点,你选择另外3个点(与之前的不同),这远远超过了2500x4种组合。 - sowizznorm
-- 这样速度应该会更快。或者,如果你愿意,可以省略平方根 -- 比较距离的平方或距离本身并没有区别。或者,使用曼哈顿距离:abs(x2-x1) + abs(y2-y1)
。这将给出一个非常粗略但是更快的距离近似值,在矩形的情况下也必须相等。 - Rody Oldenhuis假设你应该得到数字8
,但你得到了数字7
,那么你将加上数字1
(称为delta或误差校正)来进行修正。
同样地,有一个delta矩形坐标来纠正矩形。检查点(坐标)是否落在delta矩形内。
矩形坐标如下所示:
x+delta,y+delta
x-delta,y+delta
x+delta,y-delta
x-delta,y-delta
如果这个方案对你来说可以正常工作,或者你找到了更好的解决方案,请告诉我。