Abstract: 数字图像处理:第56天
Keywords: 局部阈值处理
本文最初发表于csdn,于2018年2月17日迁移至此
灰度图像-图像分割 阈值处理之局部阈值
废话开始,今天说下区域阈值(局部阈值),前面介绍的阈值都是全局阈值,也就是阈值根据全局信息产生,而作用对象也是整幅图像的全部像素,而局部阈值的产生是一个中心像素c(x,y)的邻域的一些属性来计算出一个或多个阈值以及阈值的判别式。这句话比较难懂,举个例子,假设c的邻域R,根据邻域R计算出阈值 $T_1,T_2,T_3\dots T_n$ 我们可以表示成向量 $T=(T_1,T_2,T_3\dots T_n)$ ,设计阈值判别式Q(T,pixValue)其中pix_value的值就是像素c(x,y)的灰度值,判别式返回真假,真的话像素设置为亮,否则设置成暗。
算法内容
该算法的关键点在于设计判别式Q和计算阈值向量T,因为此算法的通用性不是很强,但优点是灵活性强,可以根据不同的图片性质来设计不同的执行方案,比如下面例子中使用最简单的两种统计学参数,均值和标准差,当中心像素大于均值的n倍并且大于标准差的m倍。设置窗口大小,也就是邻域大小,参数n,参数m,最后得到较好的阈值结果。
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| void LocalThreshold(double *src,double *dst,int width,int height,int w_size,double mean_param,double std_dev_param){ double *temp=(double *)malloc(sizeof(double)*width*height);
Zero(temp, width,height); double mean_g=matrixMean(src, width, height); for(int j=w_size/2;j<height-w_size/2;j++){ for(int i=w_size/2;i<width-w_size/2;i++){ double deta=0.0; double mean=0.0; double pix_value=src[j*width+i]; for(int m=-w_size/2;m<w_size/2+1;m++){ for(int n=-w_size/2;n<w_size/2+1;n++){ mean+=src[(j+m)*width+i+n]; } } mean/=(double)(w_size*w_size); for(int m=-w_size/2;m<w_size/2+1;m++){ for(int n=-w_size/2;n<w_size/2+1;n++){ deta+=(src[(j+m)*width+i+n]-mean)*(src[(j+m)*width+i+n]-mean); } }
deta/=(double)(w_size*w_size); deta=sqrt(deta); if(pix_value>mean_param*mean_g&&pix_value>std_dev_param*deta){ temp[j*width+i]=255.0; } } } matrixCopy(temp, dst, width, height); free(temp); }
|
算法效果
总结
相比于全局阈值,局部阈值对目标大小,以及噪声敏感度强,但其缺点是设计针对性强,没有什么通用的算法,而且输入的参数多半需要分析实验产生,不能实现自动阈值处理,其优点是功能强大。
待续。。。