数字图像处理之OSTU二值化
来源:互联网 发布:赵云武力知乎 编辑:程序博客网 时间:2024/05/17 07:09
#include<stdlib.h>
bool tobinary(unsigned char *pImage, int width, int height, int biBitCount)
{
int i, j, k;
int h[256]={0};
unsigned int ip1, ip2, is1, is2=0; //存储前景和背景的灰度总和及像素个数
double w0, w1=0; //前景和背景像素的比例
double mean1, mean2=0; //前景和背景的平均灰度
double g[245]={0}; //存储类间方差
double gmax=0; //最大类间方差
unsigned char th=0; //二值化阈值
//定义变量,计算图像每行像素所占的字节数(必须是4的倍数)
int lineByte=(width * biBitCount/8+3)/4*4;
for(i=0; i<height; i++) //灰度直方图
for(j=0; j<width; j++)
{
k = *(pImage+i*lineByte+j);
h[k]++;
}
for(i=10; i<245; i++) //阈值一般不会超出这个范围
{
ip1=0; ip2=0; is1=0; is2=0;
w0=0; w1=0;
for(j=0; j<i; j++)
{
ip1+=h[j]*j; is1+=h[j];
}
mean1=ip1/is1;
w0=double(is1)/double(width*height);
for (j=i; j<256; j++)
{
ip2+=h[j]*j; is2+=h[j];
}
mean2=ip2/is2;
w1=1-w0;
g[i]=w0*w1*(mean1-mean2)*(mean1-mean2);
}
gmax=g[10];
th=10;
for(i=11; i<245; i++)
if(g[i]>gmax)
{
gmax=g[i]; th=i;
}
for(i=0; i<height; i++)
for(j=0; j<width; j++)
*(pImage+i*lineByte+j)=*(pImage+i*lineByte+j)>th?255:0;
return 1;
bool tobinary(unsigned char *pImage, int width, int height, int biBitCount)
{
int i, j, k;
int h[256]={0};
unsigned int ip1, ip2, is1, is2=0; //存储前景和背景的灰度总和及像素个数
double w0, w1=0; //前景和背景像素的比例
double mean1, mean2=0; //前景和背景的平均灰度
double g[245]={0}; //存储类间方差
double gmax=0; //最大类间方差
unsigned char th=0; //二值化阈值
//定义变量,计算图像每行像素所占的字节数(必须是4的倍数)
int lineByte=(width * biBitCount/8+3)/4*4;
for(i=0; i<height; i++) //灰度直方图
for(j=0; j<width; j++)
{
k = *(pImage+i*lineByte+j);
h[k]++;
}
for(i=10; i<245; i++) //阈值一般不会超出这个范围
{
ip1=0; ip2=0; is1=0; is2=0;
w0=0; w1=0;
for(j=0; j<i; j++)
{
ip1+=h[j]*j; is1+=h[j];
}
mean1=ip1/is1;
w0=double(is1)/double(width*height);
for (j=i; j<256; j++)
{
ip2+=h[j]*j; is2+=h[j];
}
mean2=ip2/is2;
w1=1-w0;
g[i]=w0*w1*(mean1-mean2)*(mean1-mean2);
}
gmax=g[10];
th=10;
for(i=11; i<245; i++)
if(g[i]>gmax)
{
gmax=g[i]; th=i;
}
for(i=0; i<height; i++)
for(j=0; j<width; j++)
*(pImage+i*lineByte+j)=*(pImage+i*lineByte+j)>th?255:0;
return 1;
}
这个语句要注意 w0=double(is1)/double(width*height); 因为如果不加强制转换的话,右边一个小的整数除以一个大的整数结果为0。
程序中有这么一句 int lineByte=(width * biBitCount/8+3)/4*4; 这是因为Windows系统中一行像素所占的字节数为4的倍数,因此不是4的倍数时要补充为4的倍数,这样在寻址每一个像素的时候,像素的地址为 pImage+i*lineByte+j ;而循环控制语句for(j=0; j<width; j++)中仍用width,不用lineByte,因为补充的数据不是原图像数据,我们不需要处理。
该函数在Eclipse上调试通过。
- 数字图像处理之OSTU二值化
- Win8 Metro(C#)数字图像处理--2.55OSTU法图像二值化
- 数字图像处理之数字图像基础
- 根据OSTU大津法使用Matlab实现数字图像处理segmentation的graythresh函数
- 毕业课题---之ostu算法二值化
- 数字图像处理之概述
- 【数字图像处理】(一)二值化
- 数字图像处理之点运算
- 数字图像处理之几何变换
- 数字图像处理之灰度化
- 数字图像处理之位平面图
- 数字图像处理之灰度直方图
- 数字图像处理之均衡化
- 数字图像处理之几何运算
- 数字图像处理之图像增强
- 数字图像处理之边缘检测
- 数字图象处理之浅谈数字图像处理
- 数字图像处理之归一化方法
- CodeForces 287B Pipeline(二分)
- 关于NMF(Non-negative Matr…
- 由简至美的最佳论文
- 奇异值分解(SVD) --- 几何意义
- 稀疏表示step by step(1)
- 数字图像处理之OSTU二值化
- c:forEach得到循环计数
- sicily 1020.Big Integer
- cacti监控nginx
- 网络编程毕业生总结的上学和工作期间的一些经验教训(受益匪浅)
- lucene初识
- iOS面试总结(一)
- 判定一棵二叉树是否是二叉搜索树
- “在CMD下面执行命令需要加上exe后缀才能执行“的解决方案