tracking boundary using opencv
I am trying to track/ trace boundary points in sequence from the following binary image:
I am using OpenCV (python). I am using three ways:
- 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
- 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?
- Detect contours on the Canny edge. Still some boundary is missed ??
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)
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.