http://blog.sina.com.cn/s/blog_4b9cc6db0100bbyb.html

解决方案 »

  1.   


    void FindRegion(IplImage *pImg, CvMemStorage *storage, list<CvRegion> *pRegionList)
    {
            //载入图像
            if( pImg != 0 )
            {
                    IplImage *pSignedImg = cvCreateImage(cvGetSize(pImg), 8, 1);
                    cvZero(pSignedImg);                cvCopy(pImg, pSignedImg);                CvSeq *contours = 0, *contoursTemp = 0;                 int totals = cvFindContours(pSignedImg, storage,&contours, sizeof(CvContour),    //img必须是一个二值图像 storage 用来存储的contours指向存储的第一个轮廓
                            CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
                    contoursTemp = contours;                cvCopy(pImg, pSignedImg);                list<CvRegion> regionList;        //保持区域
                    int nSignedVal = 100;                // 标记像素值                for(;contoursTemp != 0; contoursTemp = contoursTemp -> h_next)  /// 这样可以访问每一个轮廓  ====横向轮廓
                    {
                            CvRegion region;
                            memset(®ion, 0, sizeof(region));                        CvPoint *pt = (CvPoint*) cvGetSeqElem(contoursTemp, 0);
                            cvFloodFill(pSignedImg, *pt, cvScalarAll(nSignedVal), cvScalarAll(nSignedVal));                        CvRect rt = cvBoundingRect(contoursTemp);
                            region.boundRt = rt;                        int nAreaCount = 0;                        for(int h=rt.y; h<rt.y+rt.height; h++)
                            {
                                    BYTE* pDataRow = (BYTE*)(pSignedImg->imageData + h*pSignedImg->widthStep);                                for(int w=rt.x; w<rt.x+rt.width; w++)
                                    {
                                            BYTE* pData = pDataRow + w;                                        if(*pData == nSignedVal)
                                            {
                                                    *pData = 0;
                                                    nAreaCount++;
                                            }
                                    }
                            }                        region.nArea = nAreaCount;
                            //printf("nAreaCount = %d...........\n", nAreaCount);                        region.pSeqCountours = contoursTemp;                        pRegionList->push_back(region);
                    }                cvZero(pSignedImg);
                    cvReleaseImage(&pSignedImg);                return;
            }
    }void TestFindRegion()
    {
            char *pszImgPath = "c:\\holdfill.bmp";
            IplImage* pImg = NULL; //声明IplImage指针        //载入图像
            if( (pImg = cvLoadImage( pszImgPath, 0)) != 0 )
            {
                    CvMemStorage *storage = cvCreateMemStorage(0);   // 内存存储序列                list<CvRegion> regionList;
                    FindRegion(pImg, storage, ®ionList);                IplImage *pSignedImg = cvCreateImage(cvGetSize(pImg), 8, 1);
                    cvZero(pSignedImg);                int nExternalClrVal = 255;
                    int nHoleClrVal = 255;
                    for (list<CvRegion>::iterator itr=regionList.begin(); itr!=regionList.end(); itr++)
                    {
                            cvDrawContours( pSignedImg,                                                                                                        //img
                                                            itr->pSeqCountours,                                                                                        //countours
                                                            CV_RGB(nExternalClrVal, nExternalClrVal, nExternalClrVal),        //external_color
                                                            CV_RGB(nHoleClrVal, nHoleClrVal, nHoleClrVal),                                //hole_color
                                                            -2,                                                                                                                        //max_level
                                                            CV_FILLED,                                                                                                        //thick_ness
                                                            CV_AA,                                                                                                                //lines_type
                                                            cvPoint(0,0) );                                                                                                //offset
                    }                cvShowImage("img", pImg);
                    cvShowImage("pSignedImg", pSignedImg);
                    cvWaitKey(0);                cvReleaseImage(&pSignedImg);
                    cvReleaseMemStorage(&storage);      // 也要释放内存序列空间
                    cvReleaseImage(&pImg);
            }
    }typedef struct _CvRegion 
     {
             int nArea;         CvRect boundRt;
             CvSeq *pSeqCountours;
     }CvRegion, *PCvRegion;
      

  2.   

    floodfill算法,连通域标记算法都可以;
    给个floodfill算法DEMO:http://bbs.csdn.net/topics/390256087