用OpenCV求解最大连通域

在MATLAB里求解最大连通域用bwlabel就行了,在OpenCV中没有看到现成的函数,在网上 
找了一些程序,看起来头大,于是自己编了一个,抛砖引玉了这里 

本程序的主要结构是: 
1.读彩色bmp文件,提取Green通道 
2.中值滤波,Otsu二值化 
3.形态学操作去除小细节 
4.标注连通域 

5.求解最大连通域 

#include <cv.h> 
#include <highgui.h> 
#include <cxcore.h> 
#include <vector> 
#include <algorithm> 
using namespace std; 

///
void CMy20111114qian的matlab程序转opencvDlg::OnBnClickedButton1()
{
 IplImage *src = cvLoadImage("before.bmp", CV_LOAD_IMAGE_COLOR);//读取图像文件
 cvNamedWindow("origin");
 cvShowImage("origin", src);//显示原始图像
 //摄像机保存的图像是32位的,有R、G、B和Alpha通道
 //图像中实际存储顺序是B、G、R
 IplImage *blue = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);//制作一个单通道图像
 IplImage *green = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);//制作一个单通道图像
 IplImage *red = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);//制作一个单通道图像
 cvSplit(src, blue, green, red, NULL);//分割颜色通道
 cvSmooth(green, green, CV_MEDIAN, 7);//7*7中值滤波
 cvThreshold(green, green, 0.0, 255.0, CV_THRESH_BINARY | CV_THRESH_OTSU);//OTSU法二值化
 {
  IplConvKernel *element = cvCreateStructuringElementEx(5, 5, 0, 0, CV_SHAPE_ELLIPSE);//定义形态学结构指针
  cvMorphologyEx(green, green, NULL, element, CV_MOP_OPEN);//开运算,去除比结构元素小的亮点
  cvReleaseStructuringElement(&element);
 }
 cvNamedWindow("binary");
 cvShowImage("binary", green);//显示二值化图像
 {
  int color = 254;// 从254开始,因此连通域不能多于253个
  CvSize sz = cvGetSize(green);
  int w;
  int h;
  for (w=0; w<sz.width; w++)
  {
   for (h=0; h<sz.height; h++)
   {
    if (color > 0)
    {
     if (CV_IMAGE_ELEM(green, unsigned char, h, w) == 255)
     {
      cvFloodFill(green, cvPoint(w,h), CV_RGB( color,color,color));//把各连通域标记上颜色
      color--;
     }
    }
   }
  }
  cvNamedWindow("labeled");
  cvShowImage("labeled", green);//显示标记后的图像
  int colorsum[255] = {0};
  for (w=0; w<sz.width; w++)
  {
   for (h=0; h<sz.height; h++)
   {
    if (CV_IMAGE_ELEM(green, unsigned char, h, w) > 0)//不对0值计数,不可能为255
    {
     colorsum[CV_IMAGE_ELEM(green, unsigned char, h, w)]++;//统计每种颜色的数量
    }
   }
  }
  vector<int> v1(colorsum, colorsum+255);//用数组初始化vector
  int maxcolorsum = max_element(v1.begin(), v1.end()) - v1.begin();//求出最多数量的颜色
  for (w=0; w<sz.width; w++)
  {
   for (h=0; h<sz.height; h++)
   {
    if (CV_IMAGE_ELEM(green, unsigned char, h, w) == maxcolorsum)
    {
     CV_IMAGE_ELEM(green, unsigned char, h, w) = 255;//只把最多数量的颜色标为255
    }
    else
    {
     CV_IMAGE_ELEM(green, unsigned char, h, w) = 0;//其他标为0
    }
   }
  }
  cvNamedWindow("最大连通域");
  cvShowImage("最大连通域", green);//显示最大连通域
 }
 cvReleaseImage(&src);
 cvReleaseImage(&blue);
 cvReleaseImage(&green);
 cvReleaseImage(&red);
}


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值