OPENCV连通域操作

由于项目需要,要对图像中的最大连通域进行标定,并且存储。首先需要使用cvFindCountour对边缘进行标定,其实它的原理就是连通域的边缘提取;其次就是对连通域进行大小判断找出最大的连通域;最后当然就是进行Rect并且ROI了。如果有需要可以进行存储。直接上源码吧。
#include "cv.h"  
#include "cxcore.h"  
#include "highgui.h"  
   
int main( int argc, char** argv )  
{  
 //声明IplImage指针  
 IplImage* pImg = cvLoadImage("black.bmp",0);  
 IplImage* pContourImg = NULL;  
 CvMemStorage * storage = cvCreateMemStorage(0);  
 CvSeq * contour = 0;  
 CvSeq *contmax = 0;  
 int mode = CV_RETR_EXTERNAL;  
 cvShowImage( "src", pImg );  
 //为轮廓显示图像申请空间  
 //3通道图像,以便用彩色显示  
 pContourImg = cvCreateImage(cvGetSize(pImg),  
  IPL_DEPTH_8U,  
  3);  
 //copy source image and convert it to BGR image  
 cvCvtColor(pImg, pContourImg, CV_GRAY2BGR);  
 //查找contour  
 cvFindContours( pImg, storage, &contour, sizeof(CvContour),  
  mode, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));  
 //将轮廓画出     
 cvDrawContours(pContourImg, contour,  
  CV_RGB(255,0,0), CV_RGB(255, 0, 0),  
  2, 2, 8, cvPoint(0,0));  
 int area,maxArea = 10;//设面积最大值大于10Pixel  
 for(;contour;contour = contour->h_next)  
 {  
  area = fabs(cvContourArea( contour, CV_WHOLE_SEQ )); //获取当前轮廓面积  
  printf("area == %lf\n", area);  
  if(area > maxArea)  
  {  
   contmax = contour;  
   maxArea = area;  
  }  
 }  
 CvRect aRect = cvBoundingRect( contmax, 0 );  
 cvSetImageROI( pContourImg,aRect);  
 //显示图像  
 cvShowImage( "contour", pContourImg );  
 cvSaveImage("contour.bmp",pContourImg);  
 cvWaitKey(0);  
  
 //销毁窗口  
 cvDestroyWindow( "src" );  
 cvDestroyWindow( "contour" );  
 //释放图像  
 cvReleaseImage( &pImg );  
 cvReleaseImage( &pContourImg );  
 cvReleaseMemStorage(&storage);  
  
 return 0;  
}  

处理前的连通域



  1. a. 二值化  
  2. b. 得到轮廓的个数  
  3. c. 将面积小于100的轮廓删除  
  4. d. 将宽、高 比例小于1的轮廓删除  
  5. e. 把面积最大的米粒用红色框框画出来  
#include <stdio.h>  
#include <cv.h>  
#include <cxcore.h>  
#include <highgui.h>  
  
#pragma comment(lib, "ml.lib")  
#pragma comment(lib, "cv.lib")  
#pragma comment(lib, "cvaux.lib")  
#pragma comment(lib, "cvcam.lib")  
#pragma comment(lib, "cxcore.lib")  
#pragma comment(lib, "cxts.lib")  
#pragma comment(lib, "highgui.lib")  
#pragma comment(lib, "cvhaartraining.lib")  
int main( int argc, char** argv )    
{    
    IplImage* src;    
    src=cvLoadImage("black.jpg",CV_LOAD_IMAGE_GRAYSCALE);    
    IplImage* dst = cvCreateImage( cvGetSize(src), 8, 3 );    
    CvMemStorage* storage = cvCreateMemStorage(0);    
    CvSeq* contour = 0;    
    cvThreshold( src, src,120, 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 );//清空数组     
    CvSeq* _contour =contour;     
    double maxarea=0;    
    double minarea=100;    
    int n=-1,m=0;//n为面积最大轮廓索引,m为迭代索引     
    for( ; contour != 0; contour = contour->h_next )    
    {    
  
        double tmparea=fabs(cvContourArea(contour));    
        if(tmparea < minarea)     
        {    
            cvSeqRemove(contour,0); //删除面积小于设定值的轮廓     
            continue;    
        }    
        CvRect aRect = cvBoundingRect( contour, 0 );     
        if ((aRect.width/aRect.height)<1)    
        {    
            cvSeqRemove(contour,0); //删除宽高比例小于设定值的轮廓     
            continue;    
        }    
        if(tmparea > maxarea)    
        {    
            maxarea = tmparea;    
            n=m;    
        }    
        m++;    
        //  CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );//创建一个色彩值     
        CvScalar color = CV_RGB( 0, 255,255 );    
  
        //max_level 绘制轮廓的最大等级。如果等级为0,绘制单独的轮廓。如果为1,绘制轮廓及在其后的相同的级别下轮廓。     
        //如果值为2,所有的轮廓。如果等级为2,绘制所有同级轮廓及所有低一级轮廓,诸此种种。     
        //如果值为负数,函数不绘制同级轮廓,但会升序绘制直到级别为abs(max_level)-1的子轮廓。      
        cvDrawContours( dst, contour, color, color, -1, 1, 8 );//绘制外部和内部的轮廓     
    }    
    contour =_contour; /*int k=0;*/    
    int count=0;    
    for( ; contour != 0; contour = contour->h_next )    
    {    
        count++;    
        double tmparea=fabs(cvContourArea(contour));    
        if (tmparea==maxarea /*k==n*/)    
        {    
            CvScalar color = CV_RGB( 255, 0, 0);    
            cvDrawContours( dst, contour, color, color, -1, 1, 8 );    
        }    
        /*k++;*/    
    }    
    printf("The total number of contours is:%d",count);    
    cvNamedWindow( "Components", 1 );    
    cvShowImage( "Components", dst );    
    cvWaitKey(0);    
    cvDestroyWindow( "Source" );    
    cvReleaseImage(&src);    
    cvDestroyWindow( "Components" );    
    cvReleaseImage(&dst);    
    return 0;    
}    



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值