在机器视觉的图像处理中经常会用到阈值化,有时候我们需要把阈值设出来留给操作人员设定,有时候需要写死阈值,有时候需要图像自己判定阈值。在opencv中常用的阈值化操作有3种。1,固定阈值;2,自适应阈值化;3,大律法阈值。视情况而定使用哪一种方法更好。大家要用哪种把那一种方法取消注释就行。
//vs2015,opencv2.4环境下:
main函数中:
Mat dstImage;
Mat srcImage = imread("1.jpg");
#pragma region 1......固定阈值
//threshold(srcImage, dstImage, 11, 255, CV_THRESH_BINARY_INV);
#pragma endregion
#pragma region 2......进行自适应阈值化
/*
**********
adaptiveThreshold(输入图像,输出图像,向上最大值,自适应方法.平均或高斯,阈值化类型,块大小,常量)
cv::adaptiveThreshold()支持两种自适应方法,即cv::ADAPTIVE_THRESH_MEAN_C(平均)和cv::ADAPTIVE_THRESH_GAUSSIAN_C(高斯)。
在两种情况下,自适应阈值T(x, y)。通过计算每个像素周围bxb大小像素块的加权均值并减去常量C得到。
其中,b由blockSize给出,大小必须为奇数;如果使用平均的方法,则所有像素周围的权值相同;
如果使用高斯的方法,则(x,y)周围的像素的权值则根据其到中心点的距离通过高斯方程得到。
**********
*/
//int maxVal = 255;
//int blockSize = 41;
//double C = -1;
//srcImage.convertTo(srcImage, CV_8U); //先转化成单通道8位浮点数
//vector channels;
//Mat r1, r2, r3;
//split(srcImage, channels);
//r1 = channels.at(0);
//r2 = channels.at(1);
//r3 = channels.at(2);
//adaptiveThreshold(r1, r1, maxVal, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY_INV, blockSize, C); //自适应阈值化(平均),反阈值
////adaptiveThreshold(r1, r1, maxVal, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY_INV, blockSize, C); //自适应阈值化(高斯),反阈值
////adaptiveThreshold(r1, r1, maxVal, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, blockSize, C); //自适应阈值化
//int white = countNonZero(r1);
//int black = r1.size().area() - white;
//if (white < black)
//{
// r1 = ~r1; //如果图像像素大多数是黑色,反转它,使背景为白,二维码为黑
//}
//channels.at(0) = r1;
//channels.at(1) = r1;
//channels.at(2) = r1;
//merge(channels, dstImage); //转会回3通道
#pragma endregion
#pragma region 3......大律法阈值
dstImage = binarize(srcImage); //大律法阈值化,并反转像素
#pragma endregion
imshow("图片窗口", dstImage);
binarize()函数:
Mat binarize(Mat input) //大律法阈值化,并反转像素
{
Mat binarizeImage;
cvtColor(input, input, CV_BGR2GRAY);
threshold(input, binarizeImage, 0, 225, THRESH_OTSU); //使用大律法
//计算黑白像素的数目
int white = countNonZero(binarizeImage);
int black = binarizeImage.size().area() - white;
return white < black ? binarizeImage : ~binarizeImage; //如果图像像素大多数是白色,反转它
}