I have just used canny edge detection to detect a rectangle in an image. I would like to get the four corners of the rectangle
Please see my answer here: How to find corners on a Image using OpenCv
As for step 7: cvApproxPoly returns a CvSeq*. This link explains it well. As shown here, a CvSeq struct contains a total member that contains the number of elements in the sequence. In the case of a true quadrilateral, total should equal 4. If the quadrilateral is a square (or rectangle), angles between adjacent vertices should be ~90 degrees.
findContours will give you the outline points
Related
I have this image:
and I am using cv2.goodFeaturesToTrack to detect the coroners, so now I have this:
The corners are in red and the numbers show the order of which goodFeaturesToTrack got the corners.. for example, corner with number 0 is the first detected one, etc...
If I were to connect the dots based on that order, I would get a messy polygon so I thought of using a function that given a random set of points, it returns them in an order with which the polygon wouldn't intersect..
I found this function and it does exactly what I want.
However, although the polygon doesn't intersect, for this example I am not getting the same shape as the initial one (I am getting a non self-intersecting polygon but a different shape).
Does anyone have an idea to fix this? I was thinking of making cv2.goodFeaturesToTrack return an ordered set of points but I couldn't figure out how to do that.
Thank you so much!
If you want to get the polygon, you can threshold the image and extract the outer contour with findContours, using CV_RETR_EXTERNAL as the mode to obtain the outer contour and CV_CHAIN_APPROX_SIMPLE as the method. CV_CHAIN_APPROX_SIMPLE compresses horizontal, vertical, and diagonal segments and leaves only their end points (see the documentation).
If you want to use corner detection results and arrange them in correct order to make the polygon, you'll have to trace the boundary of the shape and add those corner points into a list as you find them along the boundary. For this, I think you can use findContours with CV_RETR_EXTERNAL and CV_CHAIN_APPROX_NONE to get every pixel. Still, you might not find your detected corner points exactly on the contour returned from findContours, so you'll have to use a proximity threshold.
I've been working off a variant of the opencv squares sample to detect rectangles. It's working fine for closed rectangles, but I was wondering what approaches I could take to detect rectangles that have openings ie missing corners, lines that are too short.
I perform some dilation, which closes small gaps but not these larger ones.
I considered using a convex hull or bounding rect to generate a contour for comparison but since the edges of the rectangle are disconnected, each would read as a separate contour.
I think the first step is to detect which lines are candidates for forming a complete rectangle, and then perform some sort of line extrapolation. This seems promising, but my rectangle edges won't lie perfectly horizontally or vertically.
I'm trying to detect the three leftmost rectangles in this image:
Perhaps this paper is of interest? Rectangle Detection based on a Windowed Hough Transform
Basically, take the hough line transform of the image. You will get maximums at the locations in (theta, rho) space which relate to the places where there are lines. The larger the value, the longer/straighter the line. Maybe do a threshold to only get the best lines. Then, we are trying to look for pairs of lines which are
1) parallel: the maximums occur at similar theta values
2) similar length: the values of the maximums are similar
3) orthogonal to another pair of lines: theta values are 90 degrees away from other pairs' theta values
There are some more details in the paper, such as doing the transform in a sliding window, and then using an error metric to consolidate multiple matches.
I am new to OpenCV and I was trying to extract the region bound by largest contour. It may be a simple question, but I am not able to figure it out. I tried googling too, without any luck.
I would:
Use contourArea() to find the largest closed contour.
Use boundingRect() to get the bounds of that contour.
Draw the contour using drawContours() (with thickness set to -1 to
fill the contour) and use this as a mask.
Use use the mask to set all pixels in the original image not in the
ROI to (0,0,0).
Use the bounding rectangle to extract just that area from the
original image.
Here is well explained what do you want do develop.
Basically you have to:
apply threshold to a copy of the original image;
use findContours -> output is:
vector<vector<Point>>
that stores contours;
iterate on contours to find the largest.
I have an image with a equilateral triangle and a rectangle:
And I want to detect 3 corner of the triangle only. I follow the OpenCV Harris corner detector tutorial I see that all the corner-point of the triangle have the threshold = 80 (when all the 4 corner-point of the rectangle threshold = 255). But I did not find the link between threshold and degree.
How can I find the corner that in the range of [55,65] degree, for example?
Here is the output Mat http://pastebin.com/raw.php?i=qNidEAG0
P/s: I very new to CV, hope you can give some more detail!
It seems that I found possible solution. I've implemented it on Mathematica and able to explain basic steps.
Use find corners operator and take strongest corners. Use Harris operator.
Find contours (cv::FindContours).
For each corner in each contour draw a circle and find point of intersection between circle and contour. There is no ready function for it in OpenCV and you should implement it yourself.
Now for each corner you have coordinates of three points: corner, and two points on sides of contour. It is enough to evaluate angles using dot product:
Result:
I have written algorithm to extract the points shown in the image. They form convex shape and I know order of them. How do I extract corners (top 3 and bottom 3) from such points?
I'm using opencv.
if you already have the convex hull of the object, and that hull includes the corner points, then all you need to to do is simplify the hull until it only has 6 points.
There are many ways to simplify polygons, for example you could just use this simple algorithm used in this answer: How to find corner coordinates of a rectangle in an image
do
for each point P on the convex hull:
measure its distance to the line AB _
between the point A before P and the point B after P,
remove the point with the smallest distance
repeat until 6 points left
If you do not know the exact number of points, then you could remove points until the minimum distance rises above a certain threshold
you could also do Ramer-Douglas-Peucker to simplify the polygon, openCV already has that implemented in cv::approxPolyDP.
Just modify the openCV squares sample to use 6 points instead of 4
Instead of trying to directly determine which of your feature points correspond to corners, how about applying an corner detection algorithm on the entire image then looking for which of your feature points appear close to peaks in the corner detector?
I'd suggest starting with a Harris corner detector. The OpenCV implementation is cv::cornerHarris.
Essentially, the Harris algorithm applies both a horizontal and a vertical Sobel filter to the image (or some other approximation of the partial derivatives of the image in the x and y directions).
It then constructs a 2 by 2 structure matrix at each image pixel, looks at the eigenvalues of that matrix, and calls points corners if both eigenvalues are above some threshold.