How to check if four points form a rectangle

寵の児 提交于 2019-12-21 04:15:35

问题


I am working on a shape recognition app. At this moment a set of points (x,y) is determined by corner detector (red points, img. 2.). Four of these points (in red frames, img. 2.) are vertices of a rectangle (sometimes a little deformed rectangle). What would be the best way to find them among others?

Here is an example of an input image:

And it looks like this after corner detection:


回答1:


This is not an answer to your question - it's just suggestion.

In my opinion corner detector is a bad way to detect rectangles - it will take much time to calculate all point distances as mathematician1975 suggested. You have to use another technique in this situation:

  1. That stamp is violet color, so first thing you should do is color segmentation.
  2. After you've done with step 1 you can use Houhg transform to detect lines on binary image. Or find all contours in image.
  3. And the final step is to detect rectangle.

Update:

Here's another solution that should also work in gray images.

  1. Do a threshold to convert image to 1bit (I used 200 from 255 as threshold).
  2. Find all contours in new image which have area bigger than some constant (I took 1000).
  3. Find bounding rectangle for each contour and do a check:

ContourArea / BoundingReactangleArea > constant

I take this constant as 0.9.

And this algorithm gave me next result:

Here's OpenCV code:

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);
        }
    }
}



回答2:


Calculate the set of 6 lengths that you will have between each pair of 4 distinct points. Within that set of 6 lengths if there are more than 3 distinct values, you do not have a rectangle (2 equal side lengths plus equal diagonal lengths)




回答3:


You are aware that by visually inspecting the point cloud you can already distinguish a multitude of rectangles? In other words, you will likely find many rectangles if you don't do a sort of pre-selection routine...

Anyway, aside from the method already given by @mathematician1975, you can also just check if the sides are (more or less) parallel.

Let's call @mathematician1975's method method 1 and parallel-check 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.

Note that these are both worst-case; with a bit of bookkeeping you can drastically reduce the cost of both.

Note also that method 2 needs to know beforehand that the vertices are already in the right order. If this is not the case, it'll increase the cost by a factor of 4, which is more that method 1..

May I ask how you are computing the distances?




回答4:


Consider you should have got number 8 but you got number 7, then you are going to add number 1 (called delta or error correction) to correct it.

In a similar manner have a delta rectangle coordinates to correct the rectangle. Check that point(coordinate) falls inside delta rectangle.

The rectangle coordinates are as mentioned below:

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

Let me know if this works fine for you or if you find a better solution



来源:https://stackoverflow.com/questions/12158396/how-to-check-if-four-points-form-a-rectangle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!