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

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.

Related

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

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?

Opencv blob detection and vectorization

I have a piece of flat material which has seen pieces taken off (convex pieces) and I would like to have what's left of it vectorized.
For example this picture http://www.laser-cutting.com/images/Coreplast_med.jpg
In this image's case I would like the blob of the circle and of the star identified as not part of the material anymore, their contours and the contour of the image vectorized as to be left only with what's left of the material (forget the handwriting).
Getting the contours is no problem with the cvCanny but how do I then vectoriz the contours? Is there a way to identify the blobs?
Any idea on how to proceed? I've read many blob-related questions but none helped me.
Thanks
In case you know what your shapes will look like, you could try this:
How to detect simple geometric shapes using OpenCV
Also cvFindContours as Samuel Audet said should be good for the vectorization :
http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours#findcontours
contours – Detected contours. Each contour is stored as a vector of points.
From there you can play around with your points and make whatever 2D representation/processing you want.

OpenCV findcontours returns 2 contours for each circle

I am trying to use findcontours() function in OpenCV on the image below.
findContours(img, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, cvPoint(0,0) );
When I do this query: contours.size() it returns 18, so that seems 2 contour for each circle. The circles are as you can see 1-pixel thick, how is it 2 contours? Is it one for outer and one for inner, if so, how can I force this function to detect just one contour for each circle? I thought a contour was defined as a connected sequence of pixels, 1 pixel thick.
I can't confirm this, but i think the algorithm used by this function does something equivalent to computing the gradient for each function. Which means that there will be a contour found on the outer edge and one on the inner edge, just like you suggested.
To confirm this, You can try to use an input image where the circles have been filled with white (elimininating the inner contour)
you can also test with different parameters on the findContours function
For example, try using CV_RETR_EXTERNAL instead of CV_RETR_TREE I assume the inner circle is nested within the outer one, so this should force it to return only the outer ones
You might've already figured this out but...
findContours only concerns about white objects and so recognizes each of hollowed circle as a band, thus produces two contours.
Best way is to create another image with filled circles and to apply findContoours for that image. It will give you what you want.

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/

Using contours in OpenCV?

I have a variety of contours, from which I need to draw masks. To do so, I need to use CV_FILLED when drawing the contours. However, my contours aren't closed - as in they aren't complete polygons, so the CV_FILLED thing won't work. Does anyone have any suggestions on how I can "close" my contours?
PS: For clarification, by closing I mean all segments aren't joined. Unlike a polygon, where the shape is closed off, mine is open.
In addition to trying convexHull, you can also look at trying the morphology operators erode and dilate. You can apply the erosion or dilation operators multiple times by using the iterations parameter.
Also, could you post the image with the objects you are trying to segment?