OpenCV获取彩色图像某一通道的最大连通域

#include <stdio.h>
#include <cv.h> 
#include <highgui.h> 
#include <cxcore.h> 
#include <vector> 
#include <algorithm> 

#pragma comment(lib, "cv.lib")
#pragma comment(lib, "cxcore.lib")
#pragma comment(lib, "highgui.lib")

using namespace std; 

void main()
{
	IplImage *src = cvLoadImage("wind.png", 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, 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)]++; // 统计每种颜色的数量
				}
			}
		}
		std::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);
	cvWaitKey(-1);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值