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

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

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


在示例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基于多个变量的阈值

猜你喜欢

转载自blog.csdn.net/misterjiajia/article/details/80464265
今日推荐