文章目录
- 前言
- 一、固定阈值化 —— threshold
- 二、自适应阈值化 —— adaptiveThreshold
- 三、LUT查找表
前言
图像阈值化在许多计算机视觉和图像处理任务中都是一个重要的预处理步骤。在边缘检测过程中,通过将图像转换为二值图像,可以突出图像中的边缘信息。通过选择适当的阈值,可以使边缘更加明显,以便于进一步的分析和提取。在文字识别任务中,图像阈值化可以用于将文本与背景分离。通过将图像转换为二值图像,可以增强文字的对比度,方便后续的文字检测、定位和识别。在图像分割中,通过将图像转换为二值图像,可以将感兴趣的目标与背景区域进行分离。阈值化可以将目标对象与背景进行明显的分离,从而方便后续的目标检测、跟踪或分析。
一、固定阈值化 —— threshold
threshold(src, dst, thresh, maxval, type)
thresh:阈值,用于对比源图像像素值的值。
maxval:二值化过程的最大值,只在THRESH_BINARY和THRESH_BINARY_INV两种二值化方法中才使用,但是在使用其他方法是也需要输入(随便输任何值都行,反正不起作用)
type:阈值化类型,表示如何应用阈值化。常用的固定阈值类型有:
cv::THRESH_BINARY:二值化。如果源图像像素值大于阈值,则将输出像素设置为 maxval,否则设置为 0。
cv::THRESH_BINARY_INV:反向二值化。与 cv::THRESH_BINARY 相反,如果源图像像素值大于阈值,则将输出像素设置为 0,否则设置为 maxval。
cv::THRESH_TRUNC:截断。如果源图像像素值大于阈值,则将输出像素设置为阈值,否则保持不变。
cv::THRESH_TOZERO:零化。如果源图像像素值大于阈值,则保持不变,否则将输出像素设置为 0。
cv::THRESH_TOZERO_INV:反向零化。与 cv::THRESH_TOZERO 相反,如果源图像像素值大于阈值,则将输出像素设置为 0,否则保持不变。
#include <opencv2/opencv.hpp>
#include<iostream>
using namespace std;
int main()
{
cv::Mat img = cv::imread("C:/Users/Opencv/temp/ocr.png");
cv::Mat gray, grayB, grayB_V, imgB, imgB_V;
cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
//cv::threshold(img, imgB, 125, 255, cv::THRESH_BINARY);
//cv::threshold(img, imgB_V, 125, 255, cv::THRESH_BINARY_INV);
//cv::imshow("Binary", imgB);
//cv::imshow("Binary_V", imgB_V);
cv::threshold(gray, grayB, 100, 255, cv::THRESH_BINARY); // 设置阈值=100
cv::threshold(gray, grayB_V, 100, 255, cv::THRESH_BINARY_INV);
cv::imshow("Binary", grayB);
cv::imshow("Binary_V", grayB_V);
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
注:彩色图像进行阈值化时,是对每个通道单独进行处理,最后的结果依然是彩色图像。但目前来说,一般都是对灰度图像进行阈值化处理的场景比较多。
上面第5个参数提到的5种阈值化方法都需要人为的设置一个阈值,阈值该设置为多少就需要自己判定了。OpenCV4给出了两种方法(OTSU 和 TRIANGLE)),结合图像灰度值分布特性获取二值化的阈值,并将阈值以函数返回值的形式给出。同样,虽然第三个参数thresh会自动给出,但是在调用函数的时候仍然不能缺省,需要自己随便设定一个,只是不会使用这个数值。(注:只能用在单通道的灰度图像)
使用方法就是在选择阈值化类型后,加 |
cv:: Mat gray_BT, gray_BTT;
cv::threshold(gray, gray_BT, 254, 255, cv::THRESH_BINARY | cv::THRESH_OTSU); //选择二值化类型,加THRESH_OTSU获取阈值
cv::threshold(gray, gray_BTT, 254, 255, cv::THRESH_BINARY | cv::THRESH_TRIANGLE);
二、自适应阈值化 —— adaptiveThreshold
threshold全局都使用一个阈值,对于某些光影分布不均匀的图像,无论选择什么阈值,某些局部区域都会存在些许问题。其中一个方法就是对图像进行裁剪处理,将大图裁剪为多张小图,对这些小图再分别设置合适的阈值。此外,OpenCV中提供了一个局部自适应阈值的方法——adaptiveThreshold,该函数通过均值法和高斯法自适应的计算blockSize* blockSize邻域内的阈值,之后进行二值化
adaptiveThreshold(src, dst, maxval, adaptiveMethod, thresholdType, blockSize, C):
src:输入图像,只能是单通道灰度图像 CV_8UC1。
dst:输出图像,与输入图像具有相同的大小和类型。
maxval:当源图像的像素值超过阈值时,要给输出像素设置的值。
adaptiveMethod:自适应方法,用于确定每个像素的阈值。常用的方法有:
cv::ADAPTIVE_THRESH_MEAN_C:使用邻域均值作为阈值。
cv::ADAPTIVE_THRESH_GAUSSIAN_C:使用邻域加权平均作为阈值,权重是一个高斯窗口。
thresholdType:阈值化类型,只能是THRESH_BINARY和THRESH_BINARY_INV。
blockSize:邻域尺寸,用于计算每个像素的阈值。必须是奇数(一般为3,5,7的奇数),并且大于 1。
C:从平均或加权平均中减去的常数。它用于调整阈值的灵敏度。
cv::Mat gray_ada, gray_ada2;
cv::adaptiveThreshold(gray, gray_ada, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 7, 0);
cv::adaptiveThreshold(gray, gray_ada2, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 7, 0);
原图为一个阴影图片,都采用cv::THRESH_BINARY进行二值化处理。第二张是使用threshold,人为设定阈值为100;第三张和第四张是使用OTSU 和 TRIANGLE来自动获取全局阈值;第五张和第六张是使用上述的adaptiveThreshold的cv::ADAPTIVE_THRESH_MEAN_C和cv::ADAPTIVE_THRESH_GAUSSIAN_C的结果。
三、LUT查找表
上述无论是全局阈值还是局部阈值,每个像素都是跟一个阈值进行比较。在使用二值化处理时得到的结果总是单一的0或255像素;在使用截断或零化处理时,得到的是源像素或阈值像素。OpenCV中提供了LUT查找表的映射方法,相当于提供了多个阈值进行比较,能够自定义最终结果有几种像素。通过对图像的每个像素值进行查表操作,可以高效地实现各种图像处理任务。如图像滤波中的均值滤波和中值滤波,可以看成通过定义合适的滤波函数作为查找表,对图像进行滤波操作。
cv::LUT(src, lut, dst)
src: 输入图像矩阵,只能是CV_8U(0-255),可以是单通道或多通道
lut:256个像素灰度值的查找表,单通道或者与src通道数相同(即src为多通道时,lut可以设置为单通道或相同的多通道)
dst:输出图像矩阵,其尺寸与src相同,数据类型与lut相同
int main()
{
cv::Mat img = cv::imread("C:/Users/Opencv/temp/lena.png");
cv::imshow("原图", img);
cv::Mat gray;
cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
// 固定二值化
cv::threshold(gray, grayB, 185, 255, cv::THRESH_BINARY);
cv::imshow("Binary", grayB);
//LUT表映射
uchar lut1[256];
for (int i = 0; i < 256; i++)
{
if (i <= 75)
lut1[i] = 0;
if (i > 75 && i <= 185)
lut1[i] = 125;
if (i > 185)
lut1[i] = 255;
}
cv::Mat lutTable(1, 256, CV_8UC1, lut1);
cv::Mat out0;
cv::LUT(gray, lutTable, out0);
cv::imshow("lut", out0);
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
从结果图可以看出,固定阈值设定为185,高于185的像素转换为255白色,低于185的转换为0黑色,只有两种像素。使用的LUT表,设置了三种映射关系,所以结果图有三种像素(0,125,255).