OpenCV图像二值化提供了两种函数
threshold
double threshold( InputArray src, OutputArray dst,
double thresh, double maxval, int type );
- src:待二值化的图像,图像只能是CV_8U和CV_32F两种数据类型。对于图像通道数目的要求和选择的二值化方法相关。
- dst:二值化后的图像,与输入图像具有相同的尺寸、数据类型和通道数。
- thresh:二值化的阈值。
- maxval:二值化过程的最大值,此函数只在THRESH_BINARY和THRESH_BINARY_INV两种二值化方法中才使用,但是在使用其他方法是也需要输入。
- type:选择图像二值化方法的标志。
二值化方法标志
除了最后两个 其他都比较好理解 就是作用的字面意思
最后两种标志,这两种标志是获取阈值的方法,并不是阈值的比较方法的标志,这两个标志可以和前面5种标志一起使用,例如“THRESH_BINARY| THRESH_OTSU”。前面5种标志在调用函数时都需要人为的设置阈值,如果对图像不了解设置的阈值不合理,会对处理后的效果造成严重的影响,这两个标志分别表示利用**大津法(OTSU)和三角形法(TRIANGLE)**结合图像灰度值分布特性获取二值化的阈值,并将阈值以函数返回值的形式给出。因此如果函数最后一个参数设置了这两个标志中的任何一个,那么函数第三个参数thresh将由系统自动给出,但是在调用函数的时候仍然不能缺省,只是程序不会使用这个数值。需要注意的是,目前为止OpenCV 4中针对这两个标志只支持输入CV_8UC1类型的图像。
threshold()函数全局只使用一个阈值,在实际情况中由于光照不均匀以及阴影的存在,全局只有一个阈值会使得在阴影处的白色区域也会被函数二值化成黑色,因此adaptiveThreshold()函数提供了两种局部自适应阈值的二值化方法
adaptiveThreshold
void adaptiveThreshold( InputArray src, OutputArray dst,
double maxValue, int adaptiveMethod,
int thresholdType, int blockSize, double C );
- src:待二值化的图像,图像只能是CV_8UC1数据类型。
- dst:二值化后的图像,与输入图像具有相同的尺寸、数据类型。
- maxValue:二值化的最大值。
- adaptiveMethod:自制应确定阈值的方法,分为均值法ADAPTIVE_THRESH_MEAN_C和高斯法ADAPTIVE_THRESH_GAUSSIAN_C这两种。
- thresholdType:选择图像二值化方法的标志,只能是THRESH_BINARY和THRESH_BINARY_INV。
- blockSize:自适应确定阈值的像素邻域大小,一般为3,5,7的奇数。
- C:从平均值或者加权平均值中减去的常数,可以为正,也可以为负。
该函数将灰度图像转换成二值图像,通过均值法和高斯法自适应的计算blockSize* blockSize邻域内的阈值,之后进行二值化。
示例代码:
//
// Created by smallflyfly on 2021/6/9.
//
#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main() {
cout << "OpenCV Version: " << CV_VERSION << endl;
Mat im = imread("test.jpg");
cv::resize(im, im, Size(0, 0), 0.5, 0.5);
Mat gray;
cv::cvtColor(im, gray, CV_BGR2GRAY);
Mat im1;
cv::threshold(im, im1, 125, 255, cv::THRESH_BINARY);
imshow("im1", im1);
Mat im2;
cv::threshold(im, im2, 125, 255, cv::THRESH_BINARY_INV);
imshow("im2", im2);
Mat gray1;
cv::threshold(gray, gray1, 125, 255, cv::THRESH_TOZERO);
imshow("gray1", gray1);
Mat gray2;
cv::threshold(gray, gray2, 125, 255, cv::THRESH_BINARY);
imshow("gray2", gray2);
Mat gray3;
cv::threshold(gray, gray3, 125, 255, cv::THRESH_TRUNC);
imshow("gray3", gray3);
Mat gray4;
cv::threshold(gray, gray4, 125, 255, cv::THRESH_BINARY|cv::THRESH_OTSU);
imshow("gray4", gray4);
Mat gray5;
cv::threshold(gray, gray5, 100, 255, cv::THRESH_BINARY|cv::THRESH_TRIANGLE);
imshow("gray5", gray5);
// 自适应二值化
Mat adMean, adGauss;
adaptiveThreshold(gray, adMean, 255, cv::ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 25, 0);
imshow("adMean", adMean);
adaptiveThreshold(gray, adGauss, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 75, 0);
imshow("adGauss", adGauss);
waitKey(0);
destroyAllWindows();
return 0;
}