OpenCV提取最大连通域

//选择最大区域,传进来是白底黑字
void SelectMaxRegion(Mat &Src)
{
	//---------MAt转换成IplImage-----
	Mat SrcColor;
	cvtColor(Src, SrcColor, CV_GRAY2BGR);
	IplImage *src = &IplImage(SrcColor);
	//---------MAt转换成IplImage-----

	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);   // 分割颜色通道  

	cvThreshold(green, green, 0.0, 255.0, CV_THRESH_BINARY_INV | CV_THRESH_OTSU);   // OTSU法二值化  

	//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("最大连通域");
		cvThreshold(green, green, 180, 255, CV_THRESH_BINARY_INV);
		cvShowImage("最大连通域", green);    // 显示最大连通域  
	}

	cvReleaseImage(&blue);
	cvReleaseImage(&green);
	cvReleaseImage(&red);
	cvWaitKey(-1);
}
//测试
void CCutImageVS2013Dlg::OnBnClickedTestButton1()
{
	Mat Src;
	Src = imread("D:\\测试图片\\1.jpg", 0);//读取图片 
	threshold(Src, Src, 180, 255, CV_THRESH_BINARY_INV);
	SelectMaxRegion(Src);  //白底黑字
}

原图
这里写图片描述

效果图这里写图片描述

欢迎扫码关注我的微信公众号

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值