int Otsu(unsigned char* src,int Height,int Width)
{
//histogram
float histogram[256] = {0};
for(int i=0; i < Height; i++)
{
unsigned char* p=src + Width * i;
for(int j = 0; j < Width; j++)
{
histogram[*p++]++;
}
}
//normalize histogram
int size = Height * Width;
for(int i = 0; i < 256; i++)
{
histogram[i] = histogram[i] / size; //直方图归一化
}
//average pixel value
float avgValue=0;
for(int i=0; i < 256; i++)
{
avgValue += i * histogram[i]; //整幅图像的平均灰度
}
int threshold;
float maxVariance=0;
float w = 0, u = 0;
for(int i = 0; i < 256; i++)
{
w += histogram[i]; //假设当前灰度i为阈值, 0~i 灰度的像素(假设像素值在此范围的像素叫做前景像素) 所占整幅图像的比例
u += i * histogram[i]; // (u / w)即为灰度i之前的像素(0~i)的平均灰度值: 前景像素的平均灰度值
float t = avgValue * w - u;
float variance = t * t / (w * (1 - w) ); //由公式g=w0*(u0-u)^2+w1(u1-u)^2约等于g=w0*w1*(u0-u1)^2推导而来
if(variance > maxVariance)
{
maxVariance = variance;
threshold = i;
}
}
return threshold;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(NULL);
if (hModule != NULL)
{
// 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("错误: MFC 初始化失败\n"));
nRetCode = 1;
}
else
{
// TODO: 在此处为应用程序的行为编写代码。
}
}
else
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("错误: GetModuleHandle 失败\n"));
nRetCode = 1;
}
CxImage image;
image.Load("C:\\Users\\Administrator\\Desktop\\LENA512.BMP");
int Width = image.GetWidth();
int Height = image.GetHeight();
int Band = image.GetBpp()/8;
if(1 != Band)
{
cout<<"Band Must Be One"<<endl;
return 0;
}
unsigned char* src = new unsigned char[Width * Height];
// unsigned char* src = new unsigned char[Width * Height];
int i, j;
uint8_t gray;
for(i = 0;i < Height;++i)
{
for(j = 0;j < Width;++j)
{
gray = image.GetPixelGray(j,Height - i - 1);
src[i * Width + j] = gray;
}
}
int Threshold;
Threshold = Otsu(src,Height,Width); //大津法查找阈值
for(int i = 0;i < Height;++i)
{
for(int j = 0;j < Width;++j)
{
if(src[i * Width + j] >= Threshold)
src[i * Width + j] = 255; //后景为255
else
src[i * Width + j] = 0; //前景为0,这样效果更好
}
}
CxImage outImage;
outImage.Create(Width,Height,24);
RGBQUAD color;
for(i = 0;i < Height;++i)
{
for(j = 0;j < Width;++j)
{
color.rgbRed = src[i * Width + j];
color.rgbGreen = src[i * Width + j];
color.rgbBlue = src[i * Width + j];
// outImage.SetPixelIndex(i,j, dst[i * Width + j]);
outImage.SetPixelColor(j,Height - i - 1,color);
}
}
cout<<"图像写入完成"<<endl;
outImage.Save("C:\\Users\\Administrator\\Desktop\\Ostu.bmp",CXIMAGE_FORMAT_BMP);
getchar();
return nRetCode;
}
otsu大津法
最新推荐文章于 2024-05-27 12:47:17 发布