opencv: How to detect rectangle with the not-in-order points in contours - c++

In OpenCV we can use the approxPolyDP to find the contours of an object. However, sometimes the output contours could be quite different when there are holes/blur in between the lines. For example, the actual object of the following two graphs is a rectangle but the output of approxPolyDP generates the contours that are not-in-order. Is there any well-known algorithm that can process the following points and detect a rectangular shape? If not, what is the best approach to deal with this situation?

Related

How to efficiently represent blobs in binary image with ellipse? | OpenCV

I want to represent blobs with oriented ellipse.
I have achieved this with findContours() in opencv. But I am thinking in real-time application contours or blob detector, which will perform better.
GaussianBlur(im, tempIm, Size(9, 9), 1, 1, BORDER_REFLECT);
findContours(tempIm, contours, hierarchy, RETR_TREE, CHAIN_APPROX_TC89_KCOS);
Also Blur extends the boundary of the blob, which is not-required.
Input Image
Output Image
Contours is the outline of an object and blob detector is an algorithm on top of findContours. Blob detector not only finds the boundaries, but also calculates the center and whether or not it matches certain shapes and sizes that you define. It is more heavy than findContours and you shouldn't use it if you care for performance and don't need these features.
You can use median blur instead of Gaussian, if you want to keep the image binary and do not extend contours. Also you can use dilate/erode/open/close operations and their combinations to denoise the binary image. These approaches are relatively comparable on binary images and you can test both for best performance and result and choose one for your task.
Tutorial code here describes how to represent the found contours with ellipses. cv::fitEllipse is used to create an ellipse for a contour. Then you can display it with cv::ellipse drawing function.

OpenCv Shape Dectection

I am using Opencv to detect shapes and size of material( like disc, washers, nuts and bolts of different size) on that will be held on running belt. what function would be best to distinguish between them.
I am planing to use cvFindContours( to find the shapes) and cvArcLength & cvContourArea to get their area.
Any better approach ?
This is a simple approach to shape matching:
Convert to grayscale
Smoothen the image.
Apply some morphological operations (if necessary).
Edge detect
Find contours (the same you mentioned). The contour function is hierarchical. Hence, segmenting the required (outer in most cases) contour(s) should be easy. Disc and washers can be distinguished by the hole in the contour hierarchy.
Use ApproxPolyDP to get your contour to a rough regular shape. You might be able to distinguish the shapes based on the vertex count in the contour.
Use moments to distinguish the shapes if ApproxPolyDP is not sufficient.
It works for most cases. Always provide sample images to help us assess the complexity of the problem :D.
Check for haar cascade object detection technique in opencv
here are some links....
http://coding-robin.de/2013/07/22/train-your-own-opencv-haar-classifier.html
http://www.technolabsz.com/2011/08/how-to-do-opencv-haar-training.html
For working with haar cascade u need haar kit for traing purpose..
http://kineme.net/files/haar.zip

Approximating Lines to Floor plan contours

I am using OpenCV-C++ and 1) I want to approximate the detected contours using findContours by only horizontal or vertical lines, and not by curves, as in floor plans. So can you suggest a method for the same.
2) Is there a way to remove smaller contours like tree borders, which can automate the process for every image, since removing the smaller areas with findContours() can lead to elimination of walls with smaller dimensions.
http://property.magicbricks.com/microsite/buy/provident-welworth/floor-plan.html
On what sort of image do you use the find contours? I assume you did follow this example..
findContour example
if not, please clarify.
However, why not try to first find all horizontal and vertical edges with the corresponding filters? Afterwards you can still try to find contours with the findContours function. Or you can use the hough transform, also available in opencv. hough lines within the hough lines you can easily eliminate smaller line segments.
for 2) what do youi mean by tree borders? you mean the contours of a tree on an image? it would be very helpful if you could provide an example image.
Cheers

OpenCV - find or access shape contour not surrounded by bg, only separated by an outline

I've been trying to find the contour of a single shape in a very plain background using OpenCV's findContour (I'd like to use the C++ syntax). However, it keeps on making its outline a contour and not the shape itself. I'm thinking it's because of the white edge resulted from Canny which doesn't make the shape closed.
Case A: Shape is by the image's edge
(This is not the actual input image but a simpler input image to illustrate this problem.)
Case B: Background surrounds the shape
There are the main functions I used:
findContours( grayImage, contours, hierarchy, RETR_LIST,CHAIN_APPROX_SIMPLE);
approxPolyDP(Mat(contours.at(largestContourIndex)),poly,3,true);
drawContours(output, contours, largestContourIndex, RGB(250,0,100), -1, 8, hierarchy, 0, Point() );
EDIT: Skipping edge detection gives the contour I need but I need to have the best contour approximate I can get.
Thanks in advance.
Did you try playing around with morphology operations?
If your basic problem is that the contour you're getting is on the outside of the object instead of the inside, and especially if your object are made out of so clear-cut and mostly regular shapes, than morphology might help.
I know OpenCV has implementations of dilation and erosion, as well as opening and closing operations. A very simple approach that might work in your situation is just eroding the shape a little bit (maybe 1-2-3 iterations) and then doing exactly what you are doing already. Hopefully, then, you'll get the outer contours of the eroded shape, that should actually be the inner contours of the original shape.
I think OpenCV actually implements even some more complex morphology, but as always, try the simple stuff first :D
It seems to me that the contour you are looking for is probably detected, but you are not using it. Instead you are using the largest contour. Try plotting all found contours one by one and see if it's in there.
If it is not, try inverting the canny image and repeating the process.
I still haven't found the reason why I can't get the shape contour but I found a workaround. After doing erosion and dilation, I basically have to draw a border or a rectangle on the outermost pixels of the input image for the background to surround the shape, ...
rectangle(input,Point(0,0),Point(input.cols-1,input.rows-1),Scalar(0,0,0),1,8,0);
... hence, letting Canny draw a closed shape outline and giving me the shape contour I want. I am still trying to successfully invert Canny's output like what #dvhamme has suggested but it's still giving me errors. It would be better if somebody points out how to properly get or access the shape contour but thanks everyone for the help.

How to find contours in an image in OpenCV?

I need to find all contours in an image. I know the whole findcontours () and drawContours () thing, but its using the Canny edge detector that I am having trouble with. To use find contours, you either need to use canny edge detection or threshold the image. I cannot threshold the image because this would result in several edges getting blurred out ("merging" of the edges). So I decided to use Canny Edge detection. However, when I do use it instead of getting perfect edges, I get a variety of lines with gaps in them. This prevents me from getting good contours For example instead of getting the edges of a square, I would get 4 separate lines separated by small gaps resulting in me getting 4 contours instead of one. I tried dilating, opening, closing, Gaussian blurring and basically every morphological operator, but none of these are doing the job. Some do not merge the lines, while some merge the lines with non-relevant lines too. So I was wondering does anyone have a solution on how I can get actual contours from Canny Edge detection, or if not does someone have any alternatives to get all the contours from an image?
make blob, then contours come with it. :)
http://code.google.com/p/cvblob/