一、阈值化介绍
阈值化函数就是指当图像某点的像素值高于或者低于某一个值(阈值)时统一取一值,其他时候保持不变或者变为0.通过这一方法我们可以从一张图片中得到我我们想要的部分,前提是该部分与背景灰度值有较大的差异。这一过程可以通过Opnecv中的函数thresold()函数和adaptiveThreshold()函数实现。
二、固定阈值化函数
固定阈值化函数指阈值是不变的,不随计算参考点的变化而变换,opencv中函数原型如下:
threshold( InputArray src, OutputArray dst,double thresh, double maxval, int type );
第一、二个参数是输入输出图像,有意思的是并不如源码注释里写的一样要求为8位单通道图像,事实上CV_8UC3即八位三通道彩图也可正常运行,相当于是对每个通道分别阈值化操作;
第三个参数是阈值;
第四个参数是可能会使用到的原像素替换值,具体替换方式见参数type中介绍;
第五个参数给出了阈值化的类型:
THRESH_BINARY | d s t ( x , y ) = { m a x v a l if src(x,y)>thresh 0 otherwise dst(x,y)=\begin{cases} maxval &\text {if src(x,y)>thresh}\\0&\text{otherwise}\end{cases} dst(x,y)={maxval0if src(x,y)>threshotherwise |
THRESH_BINARY_INV | d s t ( x , y ) = { 0 if src(x,y)>thresh m a x v a l otherwise dst(x,y)=\begin{cases} 0 &\text {if src(x,y)>thresh}\\maxval&\text{otherwise}\end{cases} dst(x,y)={0maxvalif src(x,y)>threshotherwise |
THRESH_TRUNC | d s t ( x , y ) = { t h r e s h if src(x,y)>thresh s r c ( x , y ) otherwise dst(x,y)=\begin{cases} thresh &\text {if src(x,y)>thresh}\\src(x,y)&\text{otherwise}\end{cases} dst(x,y)={threshsrc(x,y)if src(x,y)>threshotherwise |
THRESH_TOZERO | d s t ( x , y ) = { s r c ( x , y ) if src(x,y)>thresh 0 otherwise dst(x,y)=\begin{cases} src(x,y) &\text {if src(x,y)>thresh}\\0&\text{otherwise}\end{cases} dst(x,y)={src(x,y)0if src(x,y)>threshotherwise |
THRESH_TOZERO_INV | d s t ( x , y ) = { 0 if src(x,y)>thresh s r c ( x , y ) otherwise dst(x,y)=\begin{cases} 0 &\text {if src(x,y)>thresh}\\src(x,y)&\text{otherwise}\end{cases} dst(x,y)={0src(x,y)if src(x,y)>threshotherwise |
示例代码:
int main()
{
Mat srcImg = imread("E:\\material\\assassin.jpeg");
if (srcImg.empty())
{
cout << "图片读取错误";
return -1;
}
//cvtColor(srcImg, srcImg, COLOR_RGB2GRAY);
//srcImg.convertTo(srcImg,CV_32FC3, 1 / 255.0); //需要使用尺度变换因子1/255才可正常显示图片
imshow("原始图片", srcImg);
Mat dstImg =Mat::zeros (srcImg.size(), srcImg.type());
threshold(srcImg, dstImg, 0.6, 1, 0);
imshow("阈值化", dstImg);
waitKey(0);
return 1;
}
三、自适应阈值化函数
自适应阈值化函数是指阈值不固定,而是随着处理点变化而变化的,这样就可以针对于亮度分布差异较大的图像进行部分提取,阈值会随着区域亮度分布,阈值的确定有均值确定和高斯卷积结果确定两种,opencv中函数原型如下:
adaptiveThreshold( InputArray src, OutputArray dst,double maxValue,
int adaptiveMethod,int thresholdType, int blockSize, double C );
第一、二个参数为输入输出图像,这里就要求是单通道了,多通道图像无法运行,而且如果输入图像为浮点型也会报错;
第三个参数是可能会使用到的原像素替换值,具体替换方式见参数thresholdType中介绍;
第四个参数为阈值的确定方式,有ADAPTIVE_THRESH_GAUSSIAN_C、ADAPTIVE_THRESH_MEAN_C两种,前者即为高斯卷积确定,通过高斯卷积核与待计算参考点区域卷积所得结果减去第七个参数即为该点的阈值;后者为均值确定,通过计算参考点区域内均值减去第七个参数得到该点阈值;
第五个参数为阈值化方式,可选有THRESH_BINARY、THRESH_BINARY_INV;
第六个参数为矩形窗的大小,应该取计数值,像是5,7,11;
第七个参数为阈值的偏置;
示例代码:
int main()
{
Mat srcImg = imread("E:\\material\\assassin.jpeg");
if (srcImg.empty())
{
cout << "图片读取错误";
return -1;
}
cvtColor(srcImg, srcImg, COLOR_RGB2GRAY);
//srcImg.convertTo(srcImg,CV_32F, 1 / 255.0); //需要使用尺度变换因子1/255才可正常显示图片
imshow("原始图片", srcImg);
Mat dstImg =Mat::zeros (srcImg.size(), srcImg.type());
adaptiveThreshold(srcImg, dstImg, 255, ADAPTIVE_THRESH_MEAN_C, 0, 5, 0);
imshow("阈值化", dstImg);
waitKey(0);
return 1;
}