图像分割的方法很多,我们首先看看阈值分割法。使用阈值分割法的重点是,选取一个合适的阈值!
本示例从观察灰度图像的直方图,获得阈值。
在示例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基于多个变量的阈值