参考链接:https://blog.csdn.net/fly108108/article/details/81104330
MGV平均灰度值法uint8 mgv_threshold(uint8 *p, uint16 width, uint16 height)
{
int i, j;
int temp = 0;
for(i=0;i<height;i++)
{
for(j=0;j<width;j++)
{
temp+=*(p+i*width+j);
}
}
return (uint8)(temp/(width*height));
}
OTSU大津法
uint8 otsu_threshold(uint8 *p, uint16 width, uint16 height)
{
int pixel_count[256];
float pixel_pro[256];
int i, j, pixel_sum = width * height;
uint8 global_threshold = 0;
uint8* data = p; //指向像素数据的指针
//数组初始化
memset(pixel_count, 0, sizeof(pixel_count));
memset(pixel_pro, 0, sizeof(pixel_pro));
//统计灰度级中每个像素在整幅图像中的个数
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
pixel_count[(int)data[i * width + j]]++; //将像素值作为计数数组的下标
}
}
//计算每个像素在整幅图像中的比例
float max_pro = 0.0;
for (i = 0; i max_pro)
{
max_pro = pixel_pro[i];
}
}
//遍历灰度级[0,255]
float w0, w1, u0tmp, u1tmp, u0, u1, u, delta_tmp, delta_max = 0;
for (i = 0; i < 255; i++) // i作为阈值
{
w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = delta_tmp = 0;
for (j = 0; j < 256; j++)
{
if (j delta_max)
{
delta_max = delta_tmp;
global_threshold = i;
}
}
return global_threshold;
}
KSW最大熵值法
uint8 ksw_threshold(uint8 *p, uint16 width, uint16 height)
{
int pixel_count[256]; //每个像素值个数
uint8 global_threshold = 0; //最大熵对应的灰度
double property = 0.0; //像素所占概率
double entropy_max = -1.0; //最大熵
double entropy_front = 0.0; //前景熵
double entropy_back = 0.0; //背景熵
int i, j, k, pixel_sum = width*height; //纳入计算的总像素数
uint8* data = p; //指向像素数据的指针
memset(pixel_count, 0, sizeof(pixel_count));
//统计灰度级中每个像素在整幅图像中的个数
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
pixel_count[(int)data[i * width + j]]++; //将像素值作为计数数组的下标
}
}
for (i = 0; i < 256; i++)
{
//计算背景像素数
double back_total = 0;
for (j = 0; j < i; j++)
{
back_total += pixel_count[j];
}
//背景熵
for (j = 0; j < i; j++)
{
if (pixel_count[j] != 0)
{
property = pixel_count[j] / back_total;
entropy_back += -property * logf((float)(property));
}
}
//前景熵
for (k = i; k entropy_max) //得到最大熵
{
entropy_max = entropy_front + entropy_back;
global_threshold = i;
}
//清空本次计算熵值
entropy_front = 0.0;
entropy_back = 0.0;
}
return global_threshold;
}
EM迭代法
uint8 em_threshold(uint8 *p, uint16 width, uint16 height)
{
int pixel_count[256]; //每个像素值个数
int i, j, pixel_sum = width*height; //纳入计算的总像素数
uint8* data = p; //指向像素数据的指针
memset(pixel_count, 0, sizeof(pixel_count));
//统计灰度级中每个像素在整幅图像中的个数
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
pixel_count[(int)data[i * width + j]]++; //将像素值作为计数数组的下标
}
}
int t0 = 0;
int pixel_sum0 = 0;
for(i=0;i<height;i++)
{
for(j=0;j<width;j++)
{
pixel_sum0+=*(p+i*IMG_W+j);
}
}
t0 = pixel_sum0/pixel_sum;
int t1 = 0, t2 = 0;
int pixel_sum1 = 0, pixel_sum2 = 0;
int global_threshold = 0;
while (1)
{
for (i = 0; i < t0 + 1; i++)
{
t1 += i*pixel_count[i];
pixel_sum1 += pixel_count[i];
}
for (i = t0 + 1; i < 256; i++)
{
t2 += i*pixel_count[i];
pixel_sum2 += pixel_count[i];
}
global_threshold = (t1 / pixel_sum1 + t2 / pixel_sum2) / 2;
if (global_threshold == t0) break;
else t0 = global_threshold;
}
return (uint8)(global_threshold);
}