Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do contours returned by cv::findContours have a consistent orientation?

I am using OpenCV's cv::findContours function to extract contours in a binary image, in particular, I'm extracting a hierarchy of contours (using the CV_RETR_CCOMP flag). At some point in my further processing of those contours I need to rely on a consistent vertex orientation of these contours (i.e. counter-clockwise vs. clockwise).

Of course I can just determine that orientation myself using the sign of the contour's area (as computed by cv::contourArea(..., true)), but I wonder if that is even necessary (besides that, it won't even work for contours with an area of 0, i.e. thin lines in the source image) or if cv::findContours already guarantees a consistent orientation for the generated contours. I did check a few of the generated contours and cv::contourArea does indeed seem to return negative values for outer contours and positive values for inner contours. However, I couldn't find any actual guarantee to this effect in the OpenCV documentation.

So, is it specifically guaranteed that the contours returned by cv::findContours always have a consistent orientation? Is this documented anywhere? Or does it vary by version (mine is 2.4.5 for that matter)? Does the actual paper on the algorithm referenced in the documentation already say something about this? Or maybe someone with a little more insight into the actual implementation of OpenCV can say a little more about this than the interface documentation can?

like image 511
Christian Rau Avatar asked Jul 26 '17 09:07

Christian Rau


People also ask

How does OpenCV find contours work?

To put in simple words findContours detects change in the image color and marks it as contour. As an example, the image of number written on paper the number would be detected as contour. The part that you want to detect should be white like above numbers in 1st image.

What are OpenCV contours?

What are contours? Contours can be explained simply as a curve joining all the continuous points (along the boundary), having same color or intensity. The contours are a useful tool for shape analysis and object detection and recognition. For better accuracy, use binary images.

How do I connect OpenCV contours?

go through the first contour as it is listed until you hit the closest point. Then switch to the other list, starting from the closest point you go clockwise through the other contour until it is used up. switch back to the first contour and append the rest of their points. force them into cv2 contour format.


2 Answers

The contours returned from cv:findContours should have a consistent orientation. Outer contours should be oriented counter-clockwise, inner contours clockwise. This follows directly from the algorithm described in Appendix 1 of Suzuki's and Abe's paper.

The image is scanned line by line from top left to bottom right. When a pixel belonging to a border is found, the border is followed by looking at the neighbours of the first pixel in counter-clockwise order (see step 3.3 in the algorithm), until a non-background pixel is found. This is added to the contour and the search continues from this pixel.

The important thing is that in the first iteration the neighbour which is first looked at depends on whether it is an inner or an outer border. In case of an outer border the right-hand neighbour is visited first; in case of an inner border it is the left-hand neighbour. In the next search step the search starts from the last pixel visited.

Due to the scanning happing from top left to bottom right, on detection of an outer border it is assured that all neighbouring pixels to the left and the top of the border pixel are background pixels. With inner border, it is exactly the opposite, all neighbours to the left and the top are non-background pixels.

In combination with the different starting positions for visiting the neighbouring pixels this results in predictable orientations of the contours.

This algorithm is implemented in the icvFetchContour function which is used internally by cv:findContour. From there it is clear that the pixel are added to the contour polygon in the order in which they are visited.

As the documentation for cv::findContours specifically says that they implemented the algorithm by Suzuki et al. and as in this paper the direction and order for visiting the pixels is explicitely defined, I think one can assume that the orientation is kind of guaranteed.

like image 169
Christoph Böhme Avatar answered Oct 14 '22 02:10

Christoph Böhme


I believe step 1 and 4 of the Appendix I ( in the [Suzuki85] paper you referenced, "Topological Structural Analysis of Digitized Binary Images by Border Following" ) cover your question per the below:

(1) Select one of the following:
(a) If f i, j = 1 and f i, j - 1 = 0, then decide that the pixel ( i, j ) is the border following starting point of an outer border, increment NBD, and ( i 1, j 1 ) + ( i, j - 1 ).
(b) ...

(2) Depending on the types of the newly found border and ...

(3) From the starting point ( i, j ), follow the detected border ...

(4) If f i, j != 1, then LNBD = | f i, j | and resume the raster scan from the pixel ( i, j + 1 ). The algorithm terminates when the scan reaches the lower right corner of the picture.

like image 32
Eric Avatar answered Oct 14 '22 02:10

Eric