opencv获得最小连通域

来源:互联网 发布:2015年旅游数据统计 编辑:程序博客网 时间:2024/06/05 05:45
课题需要提取图像最小连通域,在网上看到有获得最大连通域的,在此基础修改一下,得到最小连通域,加上一些注释,方面日后理解

最大连通域 http://blog.csdn.net/augusdi/article/details/9009259

代码与总体思路变化不大,先对图像进行处理,获得二值图像,对二值图像中连通域进行颜色填充标记,再遍历图像对所填充颜色进行计数,再获得最小连通域。

#include "stdafx.h"  #include <cv.h>       #include <highgui.h>       #include <vector>       #include <algorithm>       using namespace std;         int main()  {      IplImage *src = cvLoadImage("wind.png", CV_LOAD_IMAGE_COLOR);      cvNamedWindow("原始图像");      cvShowImage("原始图像", src);          IplImage* dst = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U, 1);      cvCvtColor(src, dst, CV_BGR2GRAY);      cvNamedWindow("灰度图像");      cvShowImage("灰度图像", dst);          cvThreshold(dst, dst, 0.0, 255.0, CV_THRESH_BINARY | CV_THRESH_OTSU);//OTSU二值化           IplConvKernel *element = cvCreateStructuringElementEx(5, 5, 0, 0, CV_SHAPE_ELLIPSE);      cvMorphologyEx(dst, dst, NULL, element, CV_MOP_OPEN);//开运算,去除比结构元素小的点           cvReleaseStructuringElement(&element);      cvNamedWindow("二值图像");      cvShowImage("二值图像", dst);          int w, h;      CvSize sz = cvGetSize(dst);          int color = 254; // 不对0计数,不可能为255,所以254           for (w = 0; w < sz.width; w++)      {          for (h = 0; h < sz.height; h++)          {              if (color > 0)              {                  if (CV_IMAGE_ELEM(dst, unsigned char, h, w) == 255)                  {                      // 把连通域标记上颜色                           cvFloodFill(dst, cvPoint(w, h), CV_RGB(color, color, color));//用漫水填充法对每个连通域进行不同颜色填充,用作标记                      color--;                  }              }          }      }      cvNamedWindow("标记颜色后的图像");      cvShowImage("标记颜色后的图像", dst);          int colorsum[255] = { 0 };      for (w = 0; w<sz.width; w++)      {          for (h = 0; h<sz.height; h++)          {              if (CV_IMAGE_ELEM(dst, unsigned char, h, w) > 0)              {                  colorsum[CV_IMAGE_ELEM(dst, unsigned char, h, w)]++;//统计每种颜色的数量                   }          }      }      std::vector<int> v1(colorsum, colorsum + 255);//用数组初始化vector,v1其实就是colorsum      ///获取最大连通域时可以直接寻找最多数量染色,但是求最小时最少数量染色为0,我们这里需要获得除了染色数量为0之外的最少染色      for (int i = 0; i < 255; i++)      {          if (v1[i] == 0)          {              v1[i] = 10000;          }      }      //求出最多数量的染色,注意max_element的使用方法(改为了min-element,求容器中的最大或最小值)      int mincolorsum = min_element(v1.begin(), v1.end()) - v1.begin();//获得最多染色数量的下标      printf("%d\n", mincolorsum);//输出最多染色数量的下标        for (w = 0; w<sz.width; w++)      {          for (h = 0; h<sz.height; h++)          {              if (CV_IMAGE_ELEM(dst, unsigned char, h, w) == mincolorsum)              {                  CV_IMAGE_ELEM(dst, unsigned char, h, w) = 255;              }              else              {                  CV_IMAGE_ELEM(dst, unsigned char, h, w) = 0;              }          }      }      cvNamedWindow("最小连通域图");      cvShowImage("最小连通域图", dst);          cvWaitKey(0);      cvDestroyAllWindows();      cvReleaseImage(&src);      cvReleaseImage(&dst);          return 0;  }  



原创粉丝点击