学习OpenCV 08 阈值化操作
图像处理过程中经常会遇到这种情况:完成多层处理步骤并需要作出一个最终决定,或者将高于或低于某一值的像素置零同时其他的像素保持不变,即阈值化操作。
全局阈值cv::threshold()
cv::threshold()实现了阈值化操作的功能,其原理是给定一个数组和阈值,对于数组中每个值,根据其高于或低于这个阈值作出相应处理。
double cv::threshold(
cv::InputArray src, //输入图像
cv::OutputArray dst, //输出图像
double thresh, //阈值
double maxValue, //向上操作的最大值
int thresholdType //使用的阈值化类型
);
阈值类型 | 含义 | 操作 | 数值代码 |
cv::THRESH_BINARY | 二值化阈值 | dst=(src>thresh)?maxValue:0 | 0 |
cv::THRESH_BINARY_INV | 反二值化阈值 | dst=(src>thresh)?0:maxValue | 1 |
cv::THRESH_TRUNC | 截断 | dst=(src>thresh)?thresh:src | 2 |
cv::THRESH_TOZERO | 置0阈值 | dst=(src>thresh)?src:0 | 3 |
cv::THRESH_TOZERO_INV | 反置0阈值 | dst=(src>thresh)?0:src | 4 |
不同阈值类型对应的结果,图中水平直线对应于第一幅图中特定的阈值
自适应阈值cv::adaptiveThreshold()
cv::adaptiveThreshold()的阈值可以在整个阈值化过程中自动产生变化。
void cv::adaptiveThreshold(
cv::InoutArray src, //输入图像
cv::OutputArray dst, //输出图像
double maxValue, //向上操作的最大值
int adaptiveMethod, //均值或高斯
int thresholdType, //使用的阈值类型
int blockSize, //区域大小
double C //常数
)
cv::adaptiveThreshold()根据adaptiveMethod的设置,允许两种不同的自适应阈值方法。这两种方法都是逐个像素地计算自适应阈值,方法是通过计算每个像素位置周围的blockSize*blockSize区域的加权平均值后再减去常数C。两种均值方法如下:
- cv::ADAPTIVE_THRESH_MEAN_C,则均值时取得的均值是相等的
- cv::ADAPTIVE_THRESH_GAUSSIAN_C,则(x,y)周围的像素的权值则根据其到中心的的距离通过高斯方程得到
cv::adaptiveThreshold()中的thresholdType与cv::threshold()中的相同,上表已经罗列,注意此函数仅处理单通道8位或浮点数型图像,并且要求源图像和目标图像不同。
注意
相对于一般的阈值化操作,当图像中出现较大的明暗差异时,自适应阈值是非常有效的!!!
全局阈值与自适应阈值的比较:
int main(int argc, char**argv) {
Mat src = imread("D://somephotos//gjxq.jpg"), graysrc, dst1, dst2;
cvtColor(src, graysrc, cv::COLOR_BGR2GRAY);//将源图像先变成单通道灰度图像
imshow("gray single channel", graysrc);
threshold(graysrc, dst1, 100, 255, cv::THRESH_BINARY_INV);
adaptiveThreshold(graysrc, dst2, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY_INV, 71, 15);
imshow("二值化阈值", dst1);
imshow("自适应二值化阈值", dst2);
waitKey(0);
return 0;
}
程序结果如下:
很明显,这两个函数分别对光照差距巨大的图像处理结果中,自适应局部阈值化效果非常好。