2016-6-14日:又发现一种阈值分割法,最大熵阈值分割法 详情 http://blog.csdn.net/wenhao_ir/article/details/51671023
图像阈值化的一般目的是从灰度图像中分享目标区域和背景区域,然而仅仅通过设定固定阈值(固定阈值的求解可点此查看我写的博文)很难达到理想的分割效果。在实际应用中,我们可以通过某个像素的邻域以某种方法确定这个像素应该具有的阈值,进而保证图像中各个像素的阈值会随着周期围邻域块的变化而变化。在灰度图像中,灰度值变化明显的区域往往是物体的轮廓,所以将图像分成一小块一小块的去计算阈值往往会得出图像的轮廓,而固定阈值的方法就不行,可以把本文的结果和用固定阈值法进行二值化的结果作下对比,很容易发现这一点!(我下面作了对比哦)
OpenCV中提供了自适应阈值化函数adaptiveThreshold来实现自适应阈值处理、
函数adaptiveThreshold的原型如下:
C++: void adaptiveThreshold(InputArray src, OutputArray dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C)
点此查看官方的说明!
这里我对各参数作一个中文说明!
InputArray src:源图像
OutputArray dst:输出图像,与源图像大小一致
int adaptiveMethod:在一个邻域内计算阈值所采用的算法,有两个取值,分别为 ADAPTIVE_THRESH_MEAN_C 和 ADAPTIVE_THRESH_GAUSSIAN_C 。
ADAPTIVE_THRESH_MEAN_C的计算方法是计算出领域的平均值再减去第七个参数double C的值
ADAPTIVE_THRESH_GAUSSIAN_C的计算方法是计算出领域的高斯均值再减去第七个参数double C的值
int thresholdType:这是阈值类型,只有两个取值,分别为 THRESH_BINARY 和THRESH_BINARY_INV 具体的请看官方的说明,这里不多做解释
int blockSize:adaptiveThreshold的计算单位是像素的邻域块,邻域块取多大,就由这个值作决定
double C:在对参数int adaptiveMethod的说明中,我已经说了这个参数的作用,从中可以看出,这个参数实际上是一个偏移值调整量
从上面的说明中可以看出,使用函数adaptiveThreshold的关键是确定blockSize和C的值,明白了这两个值的意义之后,在实际项目中,应该可以根据试验法选出较为合适的值吧!
下面是一个实例的源码(源码中用到的图像的下载链接为 http://pan.baidu.com/s/1dFhVUpF):
图像处理开发资料、图像处理开发需求、图像处理接私活挣零花钱,可以搜索公众号"qxsf321",并关注!
//OpenCV版本2.4.9
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
int main( )
{
// 图像读取及判断
cv::Mat srcImage = cv::imread("hand1.jpg");
if( !srcImage.data )
return 1;
// 灰度转换
cv::Mat srcGray;
cv::cvtColor(srcImage, srcGray, CV_RGB2GRAY);
cv::imshow("srcGray", srcGray);
cv::Mat dstImage;
// 初始化自适应阈值参数
int blockSize = 5;
int constValue = 10;
const int maxVal = 255;
/* 自适应阈值算法
0:ADAPTIVE_THRESH_MEAN_C
1: ADAPTIVE_THRESH_GAUSSIAN_C
阈值类型
0: THRESH_BINARY
1: THRESH_BINARY_INV */
int adaptiveMethod = 0;
int thresholdType = 1;
// 图像自适应阈值操作
cv::adaptiveThreshold(srcGray, dstImage,
maxVal, adaptiveMethod,
thresholdType, blockSize,
constValue);
cv::imshow("dstImage", dstImage);
cv::waitKey(0);
return 0;
}