0
votes

I am trying to track/ trace boundary points in sequence from the following binary image: enter image description here

I am using OpenCV (python). I am using three ways:

  1. Apply Canny edge detection to detect edge. Problem is how to get the sequence of points? It's work fine but it's very hard to get the sequence of boundary points
  2. Ideal option is to detect contours on the binary image. Because contours return the boundary points in sequence. But openCV contour method is not detecting the boundary as shown in the results. Why is this happening?
  3. Detect contours on the Canny edge. Still some boundary is missed ??

enter image description here

Can anyone help me what's going on with OpenCV contours? Why it is not tracking the complete boundary. I am detecting contours as follows:

contours, hierarchy = cv2.findContours(thresh1,cv2.RETR_TREE ,cv2.CHAIN_APPROX_SIMPLE)  

where thresh1 is the binary image

1
In results image, the 1st image shows edge detection, 2nd image shows contours detected on edge and 3rd shows contours detected directly on the binary imageuser1388142
What do the annotations 406pts, 262pts and 1062pts indicate and where do these numbers come from ? Are they the size of the contour in points from findContours? If so, it looks like you're detecting plenty, but the third image may not be rendering well. Can you explain in more detail exactly what it is you are trying to get ? Is it all the points in the boundary? How will you map these to the boundary in next frame ?Dave Durbin
pts indicate the number of white pixels or boundary points .... I am trying to detect the boundary of binary object and get a list of all boundary points in sequence starting from top to the bottom... Due to some reason, contour detection is simply failing on the binary object... Contour detection returns the boundary points in sequence. Edge detection works pretty well but it does not return the boundary points in a sequenceuser1388142

1 Answers

1
votes

Given your simple contour, I'm not sure why you are using RETR_TREE since there are no nested contours. Have you tried using RETR_EXTERNAL instead ?

From OpenCV docs:

CV_RETR_TREE retrieves all of the contours and reconstructs a full hierarchy of nested contours.

CV_RETR_EXTERNAL retrieves only the extreme outer contours.

Also, note that CHAIN_APPROX_SIMPLE will not enumerate all points on the boundary, it will try to simplify the contour in particular it won't return multiple, sequential horizontal, vertical or diagonal points. If you want all points, use CV_CHAIN_APPROX_NONE which will force the contours algorithm to find all boundary points.

CV_CHAIN_APPROX_SIMPLE compresses horizontal, vertical, and diagonal seg- ments and leaves only their end points. For example, an up-right rectangular contour is encoded with 4 points.

CV_CHAIN_APPROX_NONE stores absolutely all the contour points.

The following code works on your image and finds 132 points:

// Load original image as grey scale
Mat image = imread("imagename.png", IMREAD_GRAYSCALE);

vector<vector<Point>> contours;
Mat hierarchy;
findContours(image, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

Swapping CV_CHAIN_APPROX_SIMPLE for CV_CHAIN_APPROX_NONE results in one contour with 737 points being returned.

You haven't included the full context of your code but note that findContours does modify the source image so if you are making multiple calls in succession using the same source image this may be something to watch out for.