FindContours的算法原理

FindContours

Comments from the Wiki

int  cvFindContours ( CvArr*  image,  CvMemStorage*  storage,  CvSeq**  first_contour, int header_size=sizeof(CvContour), int  mode=CV_RETR_LIST, int  method=CV_CHAIN_APPROX_SIMPLE,  CvPoint offset=cvPoint(0, 0) )

Finds the contours in a binary image.

Parameters:
  • image – The source, an 8-bit single channel image. Non-zero pixels are treated as 1’s, zero pixels remain 0’s - the image is treated as binary . To get such a binary image from grayscale, one may use Threshold , AdaptiveThreshold or Canny . The function modifies the source image’s content
  • storage – Container of the retrieved contours
  • first_contour – Output parameter, will contain the pointer to the first outer contour
  • header_size – Size of the sequence header,  if , and  otherwise
  • mode –

    Retrieval mode

    • CV_RETR_EXTERNAL retrives only the extreme outer contours
    • CV_RETR_LIST retrieves all of the contours and puts them in the list
    • CV_RETR_CCOMP retrieves all of the contours and organizes them into a two-level hierarchy: on the top level are the external boundaries of the components, on the second level are the boundaries of the holes
    • CV_RETR_TREE retrieves all of the contours and reconstructs the full hierarchy of nested contours
  • method –

    Approximation method (for all the modes, except CV_LINK_RUNS , which uses built-in approximation)

    • CV_CHAIN_CODE outputs contours in the Freeman chain code. All other methods output polygons (sequences of vertices)
    • CV_CHAIN_APPROX_NONE translates all of the points from the chain code into points
    • CV_CHAIN_APPROX_SIMPLE compresses horizontal, vertical, and diagonal segments and leaves only their end points
    • CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS applies one of the flavors of the Teh-Chin chain approximation algorithm.
    • CV_LINK_RUNS uses a completely different contour retrieval algorithm by linking horizontal segments of 1’s. Only the CV_RETR_LIST retrieval mode can be used with this method.
  • offset – Offset, by which every contour point is shifted. This is useful if the contours are extracted from the image ROI and then they should be analyzed in the whole image context

The function retrieves contours from the binary image using the algorithm Suzuki85 . The contours are a useful tool for shape analysis and object detection and recognition.

The function retrieves contours from the binary image and returns the number of retrieved contours. The pointer first_contour is filled by the function. It will contain a pointer to the first outermost contour or NULL if no contours are detected (if the image is completely black). Other contours may be reached fromfirst_contour using the h_next and v_next links. The sample in the DrawContours discussion shows how to use contours for connected component detection. Contours can be also used for shape analysis and object recognition - see squares.c in the OpenCV sample directory.

Note: the source image is modified by this function.


(Suzuki 1985)
Suzuki, S. (1985). "Topological structural analysis of digitized binary images by border following." Computer Vision, Graphics, and Image Processing 30(1): 32-46.

Contour Retrieving Algorithm
Four variations of algorithms described in [Suzuki85] are used in the library to retrieve
borders.
1. The first algorithm finds only the extreme outer contours in the image and
returns them linked to the list. Figure 1-2 shows these external boundaries of
W1, W2, and W3 domains.
2. The second algorithm returns all contours linked to the list. Figure 1-2 shows
the total of 8 such contours.
3. The third algorithm finds all connected components by building a two-level
hierarchical structure: on the top are the external boundaries of 1-domains and
every external boundary contains a link to the list of holes of the
corresponding component. The third algorithm returns all the connected
components as a two-level hierarchical structure: on the top are the external
boundaries of 1-domains and every external boundary contour header contains
a link to the list of holes in the corresponding component. The list can be
accessed via v_next field of the external contour header. Figure 1-2 shows
that W2, W5, and W6 domains have no holes; consequently, their boundary
contour headers refer to empty lists of hole contours. W1 domain has two holes
- the external boundary contour of W1 refers to a list of two hole contours.
Finally, W3 external boundary contour refers to a list of the single hole
contour.
4. The fourth algorithm returns the complete hierarchical tree where all the
contours contain a list of contours surrounded by the contour directly, that is,
the hole contour of W3 domain has two children: external boundary contours
of W5 and W6 domains.

DrawContours

Comments from the Wiki

void  cvDrawContours ( CvArr  *img,  CvSeq*  contour,  CvScalar  external_color,  CvScalar  hole_color, int max_level, int  thickness=1, int  lineType=8 )

Draws contour outlines or interiors in an image.

Parameters:
  • img – Image where the contours are to be drawn. As with any other drawing function, the contours are clipped with the ROI.
  • contour – Pointer to the first contour
  • external_color – Color of the external contours
  • hole_color – Color of internal contours (holes)
  • max_level – Maximal level for drawn contours. If 0, only contour is drawn. If 1, the contour and all contours following it on the same level are drawn. If 2, all contours following and all contours one level below the contours are drawn, and so forth. If the value is negative, the function does not draw the contours following after contour but draws the child contours of contour up to the  level.
  • thickness – Thickness of lines the contours are drawn with. If it is negative (For example, =CV _ FILLED), the contour interiors are drawn.
  • lineType – Type of the contour segments, see Line description

The function draws contour outlines in the image if  or fills the area bounded by the contours if  .

Example: Connected component detection via contour functions

#include "cv.h"
#include "highgui.h"

int main( int argc, char** argv )
{
    IplImage* src;
    // the first command line parameter must be file name of binary
    // (black-n-white) image
    if( argc == 2 && (src=cvLoadImage(argv[1], 0))!= 0)
    {
        IplImage* dst = cvCreateImage( cvGetSize(src), 8, 3 );
        CvMemStorage* storage = cvCreateMemStorage(0);
        CvSeq* contour = 0;

        cvThreshold( src, src, 1, 255, CV_THRESH_BINARY );
        cvNamedWindow( "Source", 1 );
        cvShowImage( "Source", src );

        cvFindContours( src, storage, &contour, sizeof(CvContour),
           CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
        cvZero( dst );

        for( ; contour != 0; contour = contour->h_next )
        {
            CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );
            /* replace CV_FILLED with 1 to see the outlines */
            cvDrawContours( dst, contour, color, color, -1, CV_FILLED, 8 );
        }

        cvNamedWindow( "Components", 1 );
        cvShowImage( "Components", dst );
        cvWaitKey(0);
    }
}

你可能感兴趣的:(opencv)