2012-08-28 164 views
10

我正在研究形状识别应用程序。此时,一组点(x,y)由角点检测器确定(红色点,img。2。)。其中四个点(红框,img。2。)是矩形的顶点(有时是一个小变形的矩形)。找到他们最好的方法是什么?如何检查四个点是否形成矩形

下面是输入图像的一个例子: Input image

它看起来像该角检测之后:

Image with detected corners

回答

11

这不是您的问题的答案 - 这仅仅是建议。

在我看来,角点检测器是一种检测矩形的不好方法 - 计算所有点距离需要很长时间,因为建议使用数学家19075。你必须在这种情况下使用另一种技术:

  1. 这张邮票是紫罗兰色,所以你应该做的第一件事就是色彩分割。
  2. 完成第1步之后,您可以使用Houhg transform来检测二值图像上的行。或者在图像中查找所有轮廓。
  3. 最后一步是检测矩形。

更新:

这里的另一个解决方案,也应该在灰度图像的工作。

  1. 执行的阈值图像转换为1位(I使用从255作为阈值)。
  2. 找到所有的面积比一些常量大的新图像轮廓(我花了)。
  3. 找到包围每个轮廓矩形,并做了检查:

ContourArea/BoundingReactangleArea>恒

我借此constant0.9

该算法给我一个结果: enter image description here

这里的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); 
     } 
    } 
} 
+0

是的,正如你指出的那样,即使对于小的输入图像,计算所有距离也会消耗大量时间。我已经检查过该解决方案。 颜色分割对于灰度图像不会有用(例子有点令人困惑,不好意思),但我用它来做RGB。 至于Hough变换我做了一些测试,它工作得很好,但经检测线**不要**交叉相互如下所示:[霍夫(http://i.imgur.com/NP8HT .JPG)。 – sowizz

+0

@sowizz看看更新。 – ArtemStorozhuk

+0

在大多数情况下,这项工作非常好,所以我打算将其标记为答案。但在某些情况下,由于没有封闭区域而失败。形态学操作当时派上用场,但几乎每种情况下都需要不同的参数,这使得它们不那么有用。任何想法如何解决这个问题?下面是这种情况的一个例子:[点击](http://i.imgur.com/mY27w.jpg) – sowizz

9

计算所述一组6米的长度,你将不得不每对之间4个不同的点。如果有多于3个不同的值,那么在6个长度的集合中,您没有矩形(2个相等的边长加上相等的对角长度)

+3

适用了一些公差,当然 –

+0

@RodyOldenhuis当然。 – mathematician1975

+0

好的解决方案,但在这个确切的问题中并不真正有用。计算所有距离即使有100个点也需要很长时间,而我通常会获得2500个左右。 – sowizz

0

考虑你应该已经得到了数8但你有数量7,那么你要添加数1 (称为增量或纠错)来纠正它。

以类似的方式有一个delta矩形坐标来校正矩形。检查点(坐标)落在delta矩形内。

矩形坐标如下所述:

x+delta,y+delta 
x-delta,y+delta 
x+delta,y-delta 
x-delta,y-delta 

让我知道这是否对你罚款,或者如果你找到一个更好的解决方案

2

您都知道,通过目测检查点云你已经可以区分大量的矩形?换句话说,如果你不做某种预选例程,你很可能会找到许多矩形......

无论如何,除了已经由@ mathematician1975给出的方法外,还可以检查边(或多或少)是平行的。

让我们打电话给@ mathematician1975的方法method 1和并行检查method 2。 Then:

%# 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. 

请注意,这些都是最坏的情况;有一些簿记你可以大大降低两者的成本。请注意0​​需要事先知道顶点已经按照正确的顺序。如果情况并非如此,则会增加成本4倍,这更多的是method 1.

请问你如何计算距离?

+0

是的,我知道有这么多的点会形成很多矩形,但我不确定在这个阶段是否有任何事情可以处理(稍后我会计算一些统计数据,以便我可以选择唯一的矩形)。 两点之间的距离按照欧几里德距离计算: '距离= sqrt((x2-x1)^ 2 +(y2-y1)^ 2);'我不确定它是否是2500x4,因为你必须选择一个点,然后选择另一个3,计算距离,然后为相同的第一个点选择另一个3点(不同于以前的点),这超出了2500x4的组合。 – sowizz

+1

@sowizz尝试'norm' - 它应该快很多。或者,如果你愿意,可以忽略平方根 - 比较距离平方或距离无关紧要。或者,使用城市街区距离:abs(x2-x1)+ abs(y2-y1)'。这将给出一个非常粗糙但更快的方式*近似于距离,即在矩形的情况下,也必须相等。 –

相关问题