【OpenCV3经典编程100例】(23)图像分割:阈值分割法

匿名 (未验证) 提交于 2019-12-03 00:21:02

图像分割的方法很多,我们首先看看阈值分割法。使用阈值分割法的重点是,选取一个合适的阈值!

本示例从观察灰度图像的直方图,获得阈值。


在示例21里面,我们计算和绘制了飞机降落那张灰度图的直方图。从这个直方图可以直观的看到,存在一个大的峰值,同时拥有大量深色的像素。这两组像素基本对应的是图像的背景和前景。

通过在两组像素之间的过渡处进行阈值化,创建二值图像。在这儿,我们选择的阈值是峰值上升前的过渡值(灰度值120)。

一、c++示例代码

//包含头文件 #include <opencv2/opencv.hpp> //命名空间 using namespace cv; using namespace std; //全局函数声明部分  //主函数 int main() { 	//【1】载入图像 	Mat image = imread("G:\\opencvtest\\testImage\\airplane.jpg"); 	//【2】检查是否载入成功 	if (image.empty()) 	{ 		printf("读取图片错误,请确认目录下是否有imread函数指定图片存在! \n "); 		return 0; 	} 	//【3】图像灰度化 	Mat grayImage; 	cvtColor(image, grayImage, COLOR_BGR2GRAY); 	//【4】图像分割:阈值分割法 	Mat binImage; 	threshold(grayImage, binImage, 120, 255, THRESH_BINARY); 	//【5】形态学滤波 	Mat erodedImage, dilatedImage; 	Mat element = getStructuringElement(MORPH_ELLIPSE, Size(5, 5)); 	morphologyEx(binImage, erodedImage, MORPH_ERODE, element, Point(-1, -1), 3); 	morphologyEx(erodedImage, dilatedImage, MORPH_DILATE, element, Point(-1, -1), 3); 	//【6】区域特征:查找轮廓 	vector<vector<Point>> contours; 	findContours(dilatedImage, contours, RETR_LIST, CHAIN_APPROX_NONE); 	//【7】区域特征:在白色图像上绘制黑色轮廓 	Mat dstImage(grayImage.size(), CV_8U, Scalar(255)); 	drawContours(dstImage, contours, -1, Scalar(0), 2); 	//【8】限定轮廓的周长,提取有效轮廓 	int cmin = 100; 	int cmax = 1000; 	vector<vector<Point>>::const_iterator itc = contours.begin(); 	while (itc != contours.end()) 	{ 		if (itc->size() < cmin || itc->size() > cmax) 			itc = contours.erase(itc); 		else 			++itc; 	} 	Mat result(grayImage.size(), CV_8UC3, Scalar(0, 0, 0)); 	drawContours(result, contours, -1, Scalar(0, 0, 255), 2); 	/*Mat mask; 	threshold(result, mask, 120, 255, THRESH_BINARY_INV); 	result.copyTo(grayImage, mask);*/ 	result.copyTo(image, result); 	//【9】显示图像 	imshow("23-彩色原图", image); 	imshow("23-阈值分割", binImage); 	imshow("23-3次腐蚀运算", erodedImage); 	imshow("23-3次膨胀运算", dilatedImage); 	imshow("23-区域轮廓图", dstImage); 	imshow("23-飞机轮廓", result); 	imshow("23-灰度图", grayImage); 	//【10】保持窗口显示 	waitKey(0); 	return 0; }

二、运行截图

图一、这是最终的效果图,我们成功在彩色图像中分割出了飞机(前景),这对于物体检测和识别很重要!


图二、彩色图像灰度化


图三、观察灰度图像的直方图,获得一个合适的阈值120,阈值分割得到飞机(前景),效果不错。


图4、3次腐蚀运算,去掉了很多黑色细节,并且填充了飞机中的白洞。目的:查找轮廓时,减少无效轮廓的数量


图5、3次膨胀运算,飞机大小变回去了,而且轮廓光滑,无白洞。这就是形态学滤波的好处!


图6、区域特征:查找轮廓,在白色图像上绘制黑色轮廓。


图8、查看轮廓contours的值,size=6,一共有6个轮廓。轮廓大小{4,18,18,597,21,1920},大小597的轮廓就是我们想要的轮廓。


图9、限定轮廓的周长,提取有效轮廓。设定最大最小值,去掉无效的轮廓,得到唯一有效的轮廓:飞机轮廓,红色标注!


三、数字图像处理知识

1图像分割定义:按照一定的规则将一幅图像分成各具特性的区域,并提取出感兴趣目标,相应的技术和过程称为图像分割。

2基于灰度值的两个基本策略:

a不连续性――区域之间(边界分割法、边缘连接分割法等)

根据图像像素灰度值的不连续性,先找到点、线(宽度为1)、边(不定宽度),再确定区域。

b相似性――区域内部(阈值分割法、面向区域的分割、数学形态学分割等)

根据图像像素灰度值的相似性,通过选择阈值,找到灰度值相似的区域,区域的外轮廓就是对象的边。

3阈值分割法

A基本思想:

确定一个合适的阈值T(阈值选定的好坏是此方法成败的关键)。

将大于等于阈值的像素作为物体或背景,生成一个二值图像。

B特点:

适用于物体与背景有较强对比的情况,重要的是背景或物体的灰度比较单一。(可通过先求背景,然后求反得到物体)

这种方法总可以得到封闭且连通区域的边界。

5阈值处理

a通过交互方式得到阈值

b通过直方图得到阈值

c通过边界特性选择阈值

d简单全局阈值

e基于多个变量的阈值

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!