void CLicensePlateView::OnMenuitem32779() //二值化
{
// TODO: Add your command handler code here
if(isfileopen!=1)
{
MessageBox("请先打开文件");
return ;
}
if(color_grey==0)
{
MessageBox("请先转换为灰阶图片");
return ;
}
BYTE *temp;
BYTE *start;
start = gdata;
temp = (BYTE*)GlobalAllocPtr(GMEM_MOVEABLE, w*h);
memcpy(temp,start,w*h);
int i,j;
int hist[256];//各个灰度值的计数
//重置计数为0
for(i=0;i<256;i++)
hist[i]=0;//清零
//计算各个灰度值的计数
for(i=0;i<h;i++)
for(j=0;j<w;j++)
{
hist[temp[i*w+j]]++;
}
float t0=0.0;
float t1=0.0;
float u=0.0;
float v=0.0;
float k=0.6;
float s=0.0;
for(i=0;i<256;i++)
{
t0+=i*hist[i];
u+=hist[i];
}
t0=t0/u;
while(true)
{
u=0;
v=0;
for(i=0;i<(int)(t0+1.5);i++)
{
v+=i*hist[i];
u+=hist[i];
}
t1=v/u;
u=0;
v=0;
for(i=(int)(t0+1.5);i<256;i++)
{
v+=i*hist[i];
u+=hist[i];
}
t1=k*(t1+v/u);
u=0;
v=0;
if((int)(t0+0.5)!=(int)(t1+0.5))
{
for(i=0;i<(int)(t0+1.5);i++)
{
v+=hist[i];
}
for(i=(int)(t0+1.5);i<256;i++)
{
u+=hist[i];
}
s=v/u;
if(s>2.5)
k-=0.001;
if(s<1.8)
k+=0.001;
t0=t1;
}
else
break;
}

//判断是否大于阈值
for(i=0;i<h;i++)
for(j=0;j<w;j++)
{
if(temp[i*w+j]>t0)
temp[i*w+j]=255;
else
temp[i*w+j]=0;
}
memcpy(start,temp,w*h);
pDC = GetDC();
Showg(w,h,gdata,pDC);
bin =1;
}
红色代码帮忙解释下

解决方案 »

  1.   

     float t0=0.0;
        float t1=0.0;
        float u=0.0;
        float v=0.0;
        float k=0.6;
        float s=0.0;
        for(i=0;i<256;i++)
        {
            t0+=i*hist[i];
            u+=hist[i];
        }
        t0=t0/u;
        while(true)
        {
            u=0;
            v=0;
            for(i=0;i<(int)(t0+1.5);i++)
            {
                v+=i*hist[i];
                u+=hist[i];
            }
            t1=v/u;
            u=0;
            v=0;
            for(i=(int)(t0+1.5);i<256;i++)
            {
                v+=i*hist[i];
                u+=hist[i];
            }
            t1=k*(t1+v/u);
            u=0;
            v=0;
            if((int)(t0+0.5)!=(int)(t1+0.5))
            {            
                for(i=0;i<(int)(t0+1.5);i++)
                {
                    v+=hist[i];
                }
                for(i=(int)(t0+1.5);i<256;i++)
                {
                    u+=hist[i];
                }
                s=v/u;
                if(s>2.5)
                    k-=0.001;
                if(s<1.8)
                    k+=0.001;
                t0=t1;
            }    
            else
                break;
        }
    这部分代码我理解的是再求某个阈值,方便后面来进行二值化,可是为什么是这样?我不太理解他的思想