贵阳市聚信天下网络科技有限公司
首页 | 联系方式 | 加入收藏 | 设为首页 | 手机站

产品目录

联系方式

联系人:业务部
电话: 00130-882723
邮箱:service@szshijibodd.com

当前位置:首页 >> 产品展示 >> 默认分类 >> 正文

Niblack和局部均值算法的二值化比较

详细信息:

Niblack二值化算法是比较简单的局部阈值方法,阈值的计算公式是T = m + k*v,其中m为以该像素点为中心的区域的平均灰度值,v是该区域的标准差,k是一个修正系数

这几天在研究静脉的图像二值化,然后百度了几次无果,要不然就是效果差,达不到心中的期待值。所以打算自己动手造一下轮子。

首先我用了局部均值法,效果挺棒的。废话不多说,看代码; 
void Mean_method(BYTE *image_in, BYTE *image_out, int xsize, int ysize)
{
/*////////////////////////////////////////////////////////////////////
// 作者:杨魁
//参数列表:
//image_in 输入图像的指针
//image_out 输出图像的指针
//xsize 图像的宽
//ysize 图像的高
////////////////////////////////////////////////////////////////////*/
int sum = 0;
int i, j, h, k;;//用于循环
int T = 0;//阈值
int num = 0;//用于自加
int w_size = 7;//窗口大小为2*w_size+1
int Area = (2 * w_size + 1)*(2 * w_size + 1);
int *d = (int *)malloc(sizeof(int)*Area);//数组空间
for (j = w_size; j < ysize - w_size; j++)
{
 for (i = w_size; i < xsize - w_size; i++)
 {
 sum = 0;
 num = 0;
 for (h = 0; h < 2 * w_size + 1; h++)
 {
 for (k = 0; k < 2 * w_size + 1; k++)
 {
 d[num++] = GetGray(image_in, xsize, i + w_size - k, j + w_size - h);
 }
 }
 for (h = 0; h < Area; h++)
 {
 sum += d[h];
 }
 T = sum / Area;
 *(image_out + j *xsize + i) = *(image_in + j *xsize + i) > T ? 255 : 0;
 }
}
free(d);
}

我写的比较简单。例如边缘我直接没有处理。待我慢慢改进。处理的图像效果如下。

效果不错吧。

然后我又换了一种被叫做Niblack的算法。代码如下:
void NiBlack(BYTE *image_in, BYTE *image_out, int xsize, int ysize)
{
/*////////////////////////////////////////////////////////////////////
// 作者:杨魁
//参数列表:
//image_in 输入图像的指针
//image_out 输出图像的指针
//xsize 图像的宽
//ysize 图像的高
////////////////////////////////////////////////////////////////////*/
int sum = 0;
int i, j, h, k;;//用于循环
int Average = 0;//平均值
int num = 0;//用于自加
int w_size = 7;//窗口大小为2*w_size+1
int Area = (2 * w_size + 1)*(2 * w_size + 1);
int *d = (int *)malloc(sizeof(int)*Area);//数组空间
int T = 0;//阈值
int S = 0;//标准差
for (j = w_size; j < ysize - w_size; j++)
{
 for (i = w_size; i < xsize - w_size; i++)
 {
 sum = 0;
 num = 0;
 for (h = 0; h < 2 * w_size + 1; h++)
 {
 for (k = 0; k < 2 * w_size + 1; k++)
 {
 d[num++] = GetGray(image_in, xsize, i + w_size - k, j + w_size - h); //求area领域内的像素值
 }
 }
 for (h = 0; h <Area; h++)
 {
 sum += d[h];//求总和
 }
 Average = sum / Area;
 sum = 0;
 for (h = 0; h < Area; h++)
 {
 sum += (d[h] * d[h]);
 }
 S = sqrt((float)sum);
 S = S / Area;
 T = Average + 0.05*S;//确定阈值
 *(image_out + j *xsize + i) = *(image_in + j *xsize + i) > T ? 255 : 0;
 }
}
free(d);
}

效果如下:

感觉并没有变化,可能是我修正系数设置的不好。好了,就写这么多。我封装了一个MyDib类,和一些常用的图像处理的算法。如果感兴趣可以一起来完善。

[简单的bmp图片操作类和常用的图像处理函数](https://github.com/yangkuiking/MyDib)

//返回某点的灰度值
int GetGray(BYTE * image_in, int xsize, int x, int y)
{
 return *(image_in + y *xsize + x);
}
//颜色反转
void Back_White(BYTE *image_des, int image_size)
{
 for (int i = 0; i < image_size; i++)
 {
 if (*(image_des + i) == 0)
 {
 *(image_des + i) = 255;
 }
 else
 {
 *(image_des + i) = 0;
 }
 }
}

源码:链接:https://pan.baidu.com/s/1P9baEotDZxrJeicLuQdnzg
提取码:f9r3