What I'm hacking now?

11 11UTC abril 11UTC 2009

Contour Retrival and DrawContours

Filed under: OpenCV — pirunga @ 5:55 pm
Tags: , , , , ,

This post will explain how to use  the function cvFindContours and cvDrawContours

Este post irá explicar como usar as funções cvFindContours e cvDrawContours

good study =)

#include "cv.h"
#include "highgui.h"
#include <stdio.h>

int main( int argc, char** argv )
{
    IplImage* src;
    if( src=cvLoadImage("pic1.png", 0) )
    {
        IplImage* dst = cvCreateImage( cvGetSize(src), 8, 3 );
        CvMemStorage* storage = cvCreateMemStorage(0);
        /* Create a Storage (it's a stack) , this is a low-level structure used
        to store dynamicaly growing data structures in our case sequences ( CvSeq )
        The parameter of cvCreateMemStorage is the block_size (size of the storage
        block in bytes). If zero size is set to default value 64K.
           Cria uma pilha, CvMemStorage é uma estrutura de baixo nível usada para
        alocar dinamicamente estruturas de dados que podem crescer, no nosso caso
        sequências ( CvSeq ). O parametro da função cvCreateMemStorage é o tamanho
        do bloco em bytes, se 0 será setado o valor padrão de 64K
        */
        CvSeq* contour = 0;
        /* Declare a CvSeq pointer */
        /* Declara o ponteiro para uma CvSeq */
        CvFont dfont;
        /*
        Declare a CvFont structure, this is used to draw text in OpenCV
        Declara uma estrutura CvFont, é utilizado para desenhar texto no Opencv
        */
        float hscale      = 0.5f;
        float vscale      = 0.5f;
        float italicscale = 0.0f;
        int  thickness    = 1;
        /* Values that would be used in CvFont:
                  hscale = horizontal scale
                  vscale = vertical scale
                  italicscale = italic scale
                  thickness = thickness (? I don't know how to explain this better
           Valores que serão utilizados pela CvFont:
                   hscale = escala horizontal
                   vscale = escala vertical
                   italicscale = escala de itálico
                   thickness = grossura da linha desenhada
        */
        char texto[255]    = "";
        /* String buffer */
        /* Uma string */
        cvInitFont (&dfont, CV_FONT_HERSHEY_SIMPLEX , hscale, vscale, italicscale, thickness, CV_AA);
        /* this function Initialize the CvFont, first parameter is the pointer to the CvFont, second
        parameter is the style of the font you can use:
                  CV_FONT_HERSHEY_SIMPLEX - normal size sans-serif font
                  CV_FONT_HERSHEY_PLAIN - small size sans-serif font
                  CV_FONT_HERSHEY_DUPLEX - normal size sans-serif font (more complex than CV_FONT_HERSHEY_SIMPLEX)
                  CV_FONT_HERSHEY_COMPLEX - normal size serif font
                  CV_FONT_HERSHEY_TRIPLEX - normal size serif font (more complex than CV_FONT_HERSHEY_COMPLEX)
                  CV_FONT_HERSHEY_COMPLEX_SMALL - smaller version of CV_FONT_HERSHEY_COMPLEX
                  CV_FONT_HERSHEY_SCRIPT_SIMPLEX - hand-writing style font
                  CV_FONT_HERSHEY_SCRIPT_COMPLEX - more complex variant of CV_FONT_HERSHEY_SCRIPT_SIMPLEX
        third to sixth parameters are those that we defined above, last is the type of the line (look to
        my cvLine example)
          esta função inicializa a estrutura CvFont, primeiro parametro é um ponteiro para a CvFont,
        segundo parametro é o estilo da fonte que pode ser uma das mostradas acima, terceiro ao sexto
        são os parametros criados acima, ultimo parametro é o tipo da linha (olhe os exemplos de cvLine)
        */
        cvNamedWindow( "Source", 1 );
        cvShowImage( "Source", src );
        /* Create a window and display the source image in it */
        /* Cria uma janela e mostra a imagem src */
        cvNamedWindow( "Components", 1 );
        cvFindContours( src, storage, &contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE  , cvPoint(0,0) );
        /* This function finds all contours in an image,
        First parameter: IplImage* source, must be 8bit single channel image, the image is treated as a binary image
        you can use cvThreshold, cvAdaptiveThreshold or Canny to get such binarized image. In my example I used a
        binary image
        Second parameter is a storage for the retrieved contours
        Third parameter is a pointer to the CvSeq*,
        Forth parameter: Size of the sequence header, >=sizeof(CvChain) if method=CV_CHAIN_CODE,
        and >=sizeof(CvContour) otherwise.
        5th parameter: its the retriaval mode:
            CV_RETR_EXTERNAL - retrive only the extreme outer contours
            CV_RETR_LIST - retrieve all the contours and puts them in the list
            CV_RETR_CCOMP - retrieve all the contours and organizes them into two-level hierarchy: top level are external
            boundaries of the components, second level are bounda boundaries of the holes
            CV_RETR_TREE - retrieve all the contours and reconstructs the full hierarchy of nested contours
        6th parameter: Approximation method (for all the modes, except CV_LINK_RUNS, which uses built-in approximation).
              CV_CHAIN_CODE - output contours in the Freeman chain code. All other methods output polygons (sequences of vertices).
              CV_CHAIN_APPROX_NONE - translate all the points from the chain code into points;
              CV_CHAIN_APPROX_SIMPLE - compress horizontal, vertical, and diagonal segments, that is, the function leaves only
              their ending points;
              CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS - apply one of the flavors of Teh-Chin chain approximation algorithm.
              CV_LINK_RUNS - use completely different contour retrieval algorithm via linking of horizontal segments of 1?s.
              Only CV_RETR_LIST retrieval mode can be used with this method.
        7th parameter: 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.

            Esta função acha todos os contornos em uma imagem.
        O primeiro parametro deve ser uma imagem de 8bits de um único canal, a imagem será tratada como uma imagem binária,
        você pode usar as funções cvThreshold, cvAdaptiveThreshold ou Canny para binarizar as imagens, no meu exemplo eu uso
        uma imagem binária logo de inicio.
        Segundo parametro: é a pilha para armazenamento dos contornos encontrados
        Terceiro parametro: u ponteiro para a CvSeq*
        4° parametro: tamenho do cabeçalho da sequencia, >=sizeof(CvChain) se o método for CV_CHAIN_CODE, senão sizeof(CvContour)
        5° parametro: é o modo como o contorno é retornado, podendo assumir os macros declarados acima,
        6° parametro é o método de aproximação (também declarado acima)
        7° Offset, é util caso seu contorno seja retirado de uma região de interesse, porém deve ser analizado no contexto completo da imagem.
            */

        cvZero( dst );
        /* This function cvZero put Zero on the CvMat* in this case I pass an IplImage that is based on an CvMat*
           Esta função imprime zeros dentro da CvMat* que é o argumento, no caso eu passo uma IplImage que é baseada
           em uma CvMat*
           */
        for( ; contour != 0; contour = contour->h_next )
        {
            /* for nothing, contour != 0, contour points to next contour */
            cvDrawContours( dst, contour, CV_RGB(0,0,255), CV_RGB(0,0,255), -1, 1, 8 ,cvPoint(0,0) );
            /* This Function draw contours in images
            first argument is the image where the contours will be drawn
            second is the contours (we get this with cvFindContours)
            third is the color of the external contour
            forth is the color of the hole defined by the contour
            5th is  the Maximal level for drawn contours. If 0, only contour is drawn.
                        If 1, the contour and all contours after it on the same level are drawn.
                        If 2, all contours after and all contours one level below the contours are drawn, etc
                        If the value is negative, the function does not draw the contours following after contour
                        but draws child contours of contour up to abs(max_level)-1 level
            6th is the line thickness, if negative the contour will be Filled;
            7th is line type
            8th is an offset to the draw
            */
            sprintf(texto, "Area: %g", cvContourArea( contour, CV_WHOLE_SEQ ));
            /* put the text between " " in the string texto,
            cvContourArea returns a double argument and is the Area inside the contour
            the value can be negative because this depends on the contour orientation
            first argument is the contour, second is the slice of the contour to be calculated
            CV_WHOLE_SEQ will use the hole sequence of the contour
            poe o texto entre "" na string texto,
            cvContourArea calcula a area definida pelo contorno, este valor pode ser negativo
            pois o valor depende da orientação do contorno.
            */

            cvPutText(dst, texto, cvPoint(15, 15), &dfont, CV_RGB(0, 255, 0));
            /* this function draw the text in the image,
            first parameter is the image to draw
            2nd is the string to be drawn
            3rd is the starting point to draw the text
            4th is the pointer to the CvFont (that defines how the font will be)
            last parameter is the color of the text.

            esta função desenha um texto na imagem
            primeiro argumento é a imagem em que o texto será desenhado, 2° é a string do
            texto, 3º é o ponto inicial para o desenho, 4° é um ponteiro para CvFont
            ultimo parametro é a cor do texto
            */
            sprintf(texto, "ArcLength: %g", cvArcLength( contour, CV_WHOLE_SEQ, -1 ));
            /* cvArcLength calculate the length of the contour
            first parameter is the contour, second is the slice (tarting and ending points
            of the curve, by default the whole curve length is calculated.)
            last parameter is: is_closed?
            >0 => is closed
            =0 => is unclosed
            <0 => look to the CV_SEQ_FLAG_CLOSED of the ((CvSeq*)curve)->flag
               Calcula o comprimento do contorno, primeiro parametro é o contorno, segundo é o
            "slice" primeiro e ultimo ponto da sequencia, por padrão calcula-se o comprimento da
            curva inteira; ultimo parametro diz se a curva é fechada ou não: 0 (não é fechada),
            >0 (é fechada), <0 ( olha na estrutura do CvSeq por uma flag 

            */
            cvPutText(dst, texto, cvPoint(15, 30), &dfont, CV_RGB(0, 255, 0));

            cvShowImage( "Components", dst );

            cvSaveImage("aaa.jpg", dst);

            cvWaitKey(0);
            /*Waits until a key is pressed */
            cvZero(dst);
        }

    }
    return 0;
}

Here I show my input image and some of the output images =)
cya ! to the next post

Deixe um comentário »

Nenhum comentário ainda.

Feed RSS para comentários sobre este post. URI de trackback

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Sair / Alterar )

Imagem do Twitter

You are commenting using your Twitter account. Sair / Alterar )

Foto do Facebook

You are commenting using your Facebook account. Sair / Alterar )

Connecting to %s

Tema: Rubric. Blog no WordPress.com.

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.