Ask Your Question
0

Recognize and track "closed line" objects [closed]

asked 2017-01-17 16:07:23 -0600

lamer gravatar image

updated 2017-01-18 04:06:06 -0600

Hi,

I would like to recognize and track an object, which is a "closed line" (...?, first figure on the attached image), and separate from other objects with OpenCV!

https://postimg.org/image/9kj0zfv6v/ ... (the little line in the middle of the first object is not necessary, just a mistake)

Anyone had idea wich is the best way can I do that?

Thank you very much!

edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by lamer
close date 2017-01-24 14:11:58.086629

2 answers

Sort by ยป oldest newest most voted
2

answered 2017-01-18 06:10:31 -0600

Another option is to detect the edges of the image and use this code to fill holes:

void fillEdgeImage(cv::Mat edgesIn, cv::Mat& filledEdgesOut) const
{
    cv::Mat edgesNeg = edgesIn.clone();

    cv::floodFill(edgesNeg, cv::Point(0,0), CV_RGB(255,255,255));
    bitwise_not(edgesNeg, edgesNeg);
    filledEdgesOut = (edgesNeg | edgesIn);

    return;
}

The only way a hole is filled is in a closed contour with holes. So, in the end, the diffference between the original (thresholded) image and the filled image are the holes, and this indicates which contours were closed and unfilled.

In your example image, the first contour will be filled, the others will stay the same.

edit flag offensive delete link more

Comments

Hi Pedro!

Thanks a lot, great idea! I tested the solution from video source (webcam), surprisingly run with good framrate, but there are a big problem in practical application, and I'm very interested in your opinion!

From this example, https://www.learnopencv.com/filling-h... the problem when I use "filling holes" in python, I have to set # Floodfill from point (x, y) the starting point. When it is (0, 0) it's fill false areas from the left top, and do not get so far as to fill the real holes. Have you any idea how to solve this?

Thanks!

lamer gravatar imagelamer ( 2017-01-19 14:44:23 -0600 )edit

Can you show images of one example that works well and one that it doesn't?

Pedro Batista gravatar imagePedro Batista ( 2017-01-20 04:38:06 -0600 )edit

Hi, thanks! Fortunately I successfully solved the mentioned problem, with your help everything works fine, but it's another question I have relates to this; Example, I have an "C" and "O" letter printed on the paper, and When I see the whole image, it's perfect, the "O" was filled. But when the "C" will be out of the picture, it is filled too, becouse the image edge is closed the line, like this: https://postimg.org/image/pv5cklmcn/

(the lower letter is an "O", but upper is a "C" on the attached picture)

Have you any idea how can I solve this?

Thanks!

lamer gravatar imagelamer ( 2017-01-20 09:23:34 -0600 )edit

To solve that, set all pixels on the edge line of the frame to zero. This will make it so that the edge does not make a contour closed.

Pedro Batista gravatar imagePedro Batista ( 2017-01-20 09:27:19 -0600 )edit

I think that too, and now the whole concept works great! Another problem was that relatively short tracking distance, as you can see at the example image, the contour is broken many times in the color based segmentation with OpenCV. I don't know exactly how it's works in OpenCV, but it looks like the thresholded picture would be much lower resolution as the input, perhaps this may be causing problem:

https://postimg.org/image/nux70qhe1/

What do you think? Thank you!

lamer gravatar imagelamer ( 2017-01-24 02:28:17 -0600 )edit

Sorry, it's my fault; I just setup wrong the erosion an dilation

lamer gravatar imagelamer ( 2017-01-24 03:50:15 -0600 )edit
2

answered 2017-01-18 05:08:08 -0600

updated 2017-01-18 05:14:38 -0600

The function cv::findContours (if called with cv2.RETR_TREE parameter) returns so-called hierarchy, which lets you find out whether the contour has an inside contours (children).

Assuming there will be no internal small holes left inside of the lines after thresholding (which can be removed using some basic morphology), none of the objects on the right-hand side of your image has any internal object. The one on left has an internal object, which is the inside of the line (and another one which is the small shape in the center). It'll be better visible is you 'revert' the colours in cv::threshold().

Learn more about the hierarchyhere: http://docs.opencv.org/trunk/d9/d8b/t...

I think, using this feature you are able to find the closed circles.

edit flag offensive delete link more

Comments

Hi,

Thank you very much for the quick answer! What do you think, is it possible to do that from cv2.VideoCapture(0) in realtime? I tried this solution, with simple images works fine, but with more complicated images only find what I want, if I set manually the # Floodfill from the point (x, y), otherwise, most of the time it makes mistake.

Thanks!

lamer gravatar imagelamer ( 2017-01-18 09:58:23 -0600 )edit

Is the comment related to my question or the Pedro's one?

mstankie gravatar imagemstankie ( 2017-01-18 13:31:29 -0600 )edit

Sorry Mstankie, unfortunately I can't able to post, just to comment today, but; The first part of the question about the realtime video capture is for everyone, and the second part is for Pedro, becouse I don't tested your solution yet, but I try it soon!

Thanks a lot!

lamer gravatar imagelamer ( 2017-01-18 13:41:39 -0600 )edit

Hi Mstankie, what do you think, maybe with your solution can I avoid this problem?

From this example, https://www.learnopencv.com/filling-h... the problem when I use "filling holes" in python, I have to set # Floodfill from point (x, y) the starting point. When it is (0, 0) it's fill false areas from the left top, and do not get so far as to fill the real holes. Have you any idea how to solve this?

Thanks!

lamer gravatar imagelamer ( 2017-01-19 14:50:05 -0600 )edit

I think you can solve the problem shown in the blog post with my approach, and I think this will be the fastest solution. But once you've got the result of flood fill that covers the whole external of the coin (set to zeros), try to subtract the new (filled) image from the original one. I imagine, the result will be just the external negative circle. All the coin shapes (its edge, the face and letters) will be removed by subtraction. You can then negate the binary image to get the true (white) mask over the coin area. Does this make sense to you?

mstankie gravatar imagemstankie ( 2017-01-24 06:14:30 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2017-01-17 16:07:23 -0600

Seen: 2,132 times

Last updated: Jan 18 '17