【发布时间】:2012-08-22 21:50:27
【问题描述】:
我正在开发一个形状识别应用程序。此时一组点 (x,y) 由角检测器确定(红点,img.2.)。其中四个点(在红色框中,img.2.)是一个矩形的顶点(有时是一个有点变形的矩形)。找到它们的最佳方式是什么?
以下是输入图像的示例:
角点检测后是这样的:
【问题讨论】:
标签: matlab image-processing shape-recognition
我正在开发一个形状识别应用程序。此时一组点 (x,y) 由角检测器确定(红点,img.2.)。其中四个点(在红色框中,img.2.)是一个矩形的顶点(有时是一个有点变形的矩形)。找到它们的最佳方式是什么?
以下是输入图像的示例:
角点检测后是这样的:
【问题讨论】:
标签: matlab image-processing shape-recognition
这不是对您问题的回答 - 这只是建议。
在我看来,角检测器是检测矩形的不好方法 - 正如 mathematician1975 建议的那样,计算所有点距离需要很长时间。在这种情况下,您必须使用另一种技术:
更新:
这是另一种也适用于灰色图像的解决方案。
ContourArea / BoundingReactangleArea > 常量
我将此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 个长度。如果有超过 3 个不同的值,则在这 6 个长度的集合中,您没有矩形(2 个相等的边长加上相等的对角线长度)
【讨论】:
您是否知道,通过目视检查点云,您已经可以区分多个矩形?换句话说,如果您不进行某种预选例程,您可能会发现很多矩形......
无论如何,除了@mathematician1975 已经给出的方法之外,您还可以检查边是否(或多或少)平行。
让我们调用@mathematician1975 的方法method 1 和并行检查method 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.
请注意,这些都是最坏的情况;通过一些簿记,您可以大大降低两者的成本。
还要注意method 2 需要事先知道顶点的顺序是正确的。如果不是这样,成本会增加 4 倍,比method 1. 还要多。
请问您是如何计算距离的?
【讨论】:
distance = sqrt( (x2-x1)^2 + (y2-y1)^2 );,我不确定它是否是 2500x4,因为您必须选择一个点,然后选择另一个 3,计算距离,然后对于同一个拳头点,您选择另一个 3超过 2500x4 组合的点(不同于以前的点)。
norm——应该会快很多。或者,如果您愿意,只需省略平方根——比较距离的平方或距离并不重要。或者,使用城市街区距离:abs(x2-x1) + abs(y2-y1)。这将给出一个非常粗略但更快的距离近似值,如果是矩形,它也必须相等。
考虑你应该有号码8,但你有号码7,那么你将添加号码1(称为增量或纠错)来更正它。
以类似的方式有一个delta矩形坐标来校正矩形。检查点(坐标)是否在 delta 矩形内。
矩形坐标如下:
x+delta,y+delta
x-delta,y+delta
x+delta,y-delta
x-delta,y-delta
让我知道这是否适合您或者您是否找到了更好的解决方案
【讨论】: