|
发表于 2021-3-30 17:16:08
|
显示全部楼层
本帖最后由 wochai 于 2021-3-30 17:19 编辑
OSTU算法(最大类间方差法)自适应计算二值化阈值
我以前做的VC6源码,现在要理清思路要点时间,你直接网上查可能还快点.
BYTE GrayToBlackWhite_Otsu(BYTE* SrcData, BYTE* DestData, int w, int h )
{
long i,j,k,iNO;
long PixelNumber ;
int Threshold = 0;
long Histgram[256];
long AllSum=0, SumSmall=0, SumBig=0, PartSum=0;
int AllPixelNumber=0;
long PixelNumberSmall=0, PixelNumberBig=0;
double ProbabilitySmall=0, ProbabilityBig=0, Probability=0, MaxValue=-1;
PixelNumber = w*h ;
for(i=0;i<256;i++) Histgram = 0; //置零;
for(j=0;j<w;j++)
for (k=0;k<h;k++)
{
iNO =NO(j,k,w);//点的序号(从左上角开始)
Histgram[*(SrcData+iNO)] += 1; //统计图像的直方图
}
for(i=0;i<256;i++)
{
AllSum += i * Histgram; // 质量矩
AllPixelNumber += Histgram; // 质量
}
for(i=0;i<256;i++)
{
PixelNumberSmall += Histgram;
PixelNumberBig = AllPixelNumber - PixelNumberSmall;
if( PixelNumberBig == 0 ) break;
SumSmall += i * Histgram;
SumBig = AllSum - SumSmall;
ProbabilitySmall = (double)(SumSmall) / PixelNumberSmall;
ProbabilityBig = (double)(SumBig) / PixelNumberBig;
//Probability = PixelNumberSmall * PixelNumberBig * (ProbabilityBig - ProbabilitySmall) * (ProbabilityBig - ProbabilitySmall);
Probability = PixelNumberSmall * ProbabilitySmall * ProbabilitySmall + PixelNumberBig * ProbabilityBig * ProbabilityBig;
if( Probability > MaxValue )
{
MaxValue = Probability;
Threshold = i;
}
}
for(j=0;j<w;j++)
for (k=0;k<h;k++)
{
iNO =NO(j,k,w);//点的序号(从左上角开始)
if( *(SrcData+iNO)<= Threshold )
{
*(DestData+iNO) = 0;
*(DestData+iNO+1) = 0;
*(DestData+iNO+2) = 0;
}
else
{
*(DestData+iNO) = 255;
*(DestData+iNO+1) = 255;
*(DestData+iNO+2) = 255;
}
}
return(Threshold);
}
|
|