關於opencv中的CvChain 結構

今天原本想寫一個圖像橢圓擬合的,使用到opencv庫。主要想借助opencv裏的cvFindContours函數先獲得圖像中的全部輪廓,接着對每個contours->h_next 進行下面的一樣操做。contours這個變量是CvSeq 類型的,是opencv中一個基礎的動態庫。我本來打算將contours這個序列轉化獲得該輪廓各點所在的位置,即將contours 裝換成CvPoint 類型的變量,獲得輪廓全部的點以後好進一步對它們進行橢圓的擬合。擬合的函數是經過一個cvFitEllipse2(CvArr* points) 這個函數來的。當我直接將contours(CvSeq)做爲參數時,編譯器固然不給經過,畢竟接受的參數類型不一致。
   可是想到opencv裏面有一個cvDrawContours 的函數,它的做用就是畫輪廓圖的。那麼,它在畫的時候,勢必要得到輪廓像素所在的位置,所以,就查找opencv源代碼,該函數在一個\src\cvcore\cxdrawing.cpp的文件中實現。實現以下:

.......

while( (contour = (CvSeq*)cvNextTreeNode( &iterator )) != 0 ) { CvSeqReader reader; int i, count = contour->total; int elem_type = CV_MAT_TYPE(contour->flags); void* clr = (contour->flags & CV_SEQ_FLAG_HOLE) == 0 ? ext_buf : hole_buf;函數

cvStartReadSeq( contour, &reader, 0 );
    if( thickness < 0 )
        pts.resize(0);

    if( CV_IS_SEQ_CHAIN_CONTOUR( contour ))
    {
        cv::Point pt = ((CvChain*)contour)->origin; //!!!!!!!!這裏就是將contours轉換爲points的
        cv::Point prev_pt = pt;
        char prev_code = reader.ptr ? reader.ptr[0] : '\0';

        prev_pt += offset;

        for( i = 0; i < count; i++ )
        {
            char code;
            CV_READ_SEQ_ELEM( code, reader );

            assert( (code & ~7) == 0 );

            if( code != prev_code )
            {
                prev_code = code;
                if( thickness >= 0 )
                    cv::ThickLine( img, prev_pt, pt, clr, thickness, line_type, 2, 0 );
                else
                    pts.push_back(pt);
                prev_pt = pt;
            }

........code

上面標註的CvChain 結構在opencv的幫助文檔中並無找獲得,好吧,在代碼中繼續追蹤它的定義所在,CvChain 的結構定義以下:對象

typedef struct CvChain { CV_SEQUENCE_FIELDS() /這一部分的定義和CvSeq 結構的定義相同/ CvPoint origin; /!!!!此處的origin 變量就是輪廓開始的點/ } CvChain;繼承

所以從功能上來講,CvChain 結構不如說是CvSeq 」派生「來的(可是C中沒有面向對象的概念),但此處的定義與繼承或派生類似,姑且能夠這麼看吧。ip

固然,origin變量記錄的只是一條輪廓的開始位置,並不包含所有的輪廓像素的位置信息!要想獲取獲得所有位置,還得另想辦法。能想到的辦法就是利用種子生長類似的原理,使用8-鄰域對頭像素追宗,但彷佛花費稍微高了點。
相關文章
相關標籤/搜索