二值图像介绍
定义:二值图像首先是单通道,其次是非黑(0)即白(255)。
应用:二值图像在图像处理、对象检测与测量、缺陷检测、模式识别、机器人视觉等方面都有很重要的应用
图像阈值化分割
图像阈值化分割是指使用阈值对图像进行分割,基于一个简单的阈值T实现对图像二分类的分割,这是最简单的阈值化分割方法。
基于这个阈值,用阈值化分割方法来实现对图像的二分类分割,即像素值大于T的设为白色(255),像素值小于或等于T的设为黑色(0),最终得到二值图像。
OpenCV中的阈值化分割函数:
double threshold( InputArray src, OutputArray dst,
double thresh, double maxval, int type );
其中:
src与dst分别表示输入图像和输出图像,支持单通道与多通道,数据类型支持CV_8U与CV_32F;
thresh表示阈值;
maxval表示最大值,当图像数据类型为CV_8U时,其最大值为255,当图像数据类型为CV_32F时,其最大值为1.0;
type表示阈值化方法,❑THRESH_BINARY:二值化。❑THRESH_BINARY_INV:二值化反。❑THRESH_TRUNC:阈值截断。❑THRESH_TOZERO:阈值取零。❑THRESH_TOZERO_INV:阈值取零反。一般选THRESH_BINARY,具体效果看下图;
返回值:如果使用Otsu或Triangle方法,则返回计算出的阈值。
代码演示:
cv::Mat src = cv::imread("./img/mini2_castle.jpg");
if (src.empty()) {
qDebug() << "image load failed!";
return 0;
}
cv::Mat gray;
cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
cv::Mat binary;
// thresh怎么得来?127?
cv::threshold(gray, binary, 127, 255, cv::THRESH_BINARY);
cv::imshow("THRESH_BINARY", binary);
cv::threshold(gray, binary, 127, 255, cv::THRESH_BINARY_INV);
cv::imshow("THRESH_BINARY_INV", binary);
cv::threshold(gray, binary, 127, 255, cv::THRESH_TRUNC);
cv::imshow("THRESH_TRUNC", binary);
cv::threshold(gray, binary, 127, 255, cv::THRESH_TOZERO);
cv::imshow("THRESH_TOZERO", binary);
cv::threshold(gray, binary, 127, 255, cv::THRESH_TOZERO_INV);
cv::imshow("THRESH_TOZERO_INV", binary);
效果:
此处src为单通道灰度图片,如果src为三通道彩色图片(代码修改如下):
cv::Mat gray = src.clone();
// cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
cv::Mat binary;
,则效果如下图:
由此可见,想要得到二值图片,则输入必须为为灰度图片。
如代码中所见thresh是怎么确定的呢??图像二值化的阈值计算方法有很多,单从算法类型上来说,可以分为全局阈值计算和局部阈值计算(自适应阈值计算)两大类。OpenCV支持两种经典的全局阈值计算方法,分别是大津法与三角法。自适应阈值计算方法支持均值与高斯自适应两种。
全局阈值之大律法
该方法最早是由大津展之提出的,所以通常称为大津法。该方法主要基于图像灰度直方图信息,通过计算最小类内方差来寻找阈值T,并根据阈值T将图像分为前景(白色)或者背景(黑色)。
OpenCV可以通过threshold函数的type参数来设置是否支持大津法,当type参数设置为THRESH_OTSU,表示支持大律法。当使用大律法自动计算阈值时,threshold函数的输入图像(src)必须是单通道灰度图像。
首先需要把输入的图像转换为灰度图像,然后调用threshold函数完成二值化。
代码实现:
cv::Mat src = cv::imread("./img/mini2_castle.jpg");
if (src.empty()) {
qDebug() << "image load failed!";
return 0;
}
cv::Mat gray = src;
cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
cv::Mat binary;
cv::threshold(gray, binary, 0,<