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