📄 bmpdisplayview.cpp
字号:
}
if((vEZ[i][j]==0)&&(mj<=30)&&(mj>=10))
{
mj=0;
yxmj++;
}
}
if((yxmj>=1))
v[i]=yxmj;
mj=0;
yxmj=0;
}
for(i=1;i<width-1;i++)
if(v[i]==0)
for(int s=1;s<height-1;s++)
{
temp3[s*Dibwidth+i*3+1]=temp3[s*Dibwidth+i*3+2]=temp3[s*Dibwidth+i*3]=0;
}
for(i=0;i<700;i++)
{
if(h[i]!=0)
for(int s=1;s<width-1;s++)
{
temp3[i*Dibwidth+s*3+1]=temp3[i*Dibwidth+s*3+2]=temp3[i*Dibwidth+s*3]=255;
}
}
for(i=0;i<800;i++)
for(int j=0;j<360;j++)
tEZ[i][j]=0;
for(i=1;i<height-1;i++)
for(int j=1;j<width-1;j++)
if(temp3[i*Dibwidth+j*3]==255)
tEZ[i][j]=1;
pDoc->rlpBuf=temp3;
pDoc->rflag=1;
}
void CBmpDisplayView::OnQyqd() //确定区域的大概位置
{
CBmpDisplayDoc *pDoc=GetDocument();
int Lbpx=0;
int Lbpy=0;
int l=0;
int h=0;
int m=0;
int n=0;
int q=0;
int r=0;
for(int i=5;i<720;i++)
for(int j=45;j<350/2;j++)
{
if((tEZ[i][j]==1)&&(tEZ[i][j-1]==1)
&&(tEZ[i][j+1]==1)&&(tEZ[i+1][j]==1))
{
m=j;
Lbpx=j;
for(int s=350;s>j;s--)
{
if((tEZ[i][s]==1)&&(tEZ[i][s-1]==1)
&&(tEZ[i][s+1]==1)&&(tEZ[i-1][s]==1)&&(tEZ[i+1][s]==1))
{
n=s;
s=0;
}
l=n-m;
if(l<=100)
l=100;
if(l>=150)
l=100;
}
s=i;
while(tEZ[s][j]!=0)
s++;
q=s;
s=i;
while(tEZ[s][j]!=0)
s--;
r=s;
h=q-r;
if(h<35)
h=35;
Lbpy=r;
i=720;
j=350;
}
}
pDoc->Lbpx=Lbpx-10;
pDoc->Lbl=l+15;
pDoc->Lbpy=Lbpy-5;
pDoc->Lbh=h+20;
pDoc->yflag=1;
pDoc->qflag=1;
}
void CBmpDisplayView::OnJqdw() //基于蓝色底纹实现精确定位
{
int width,height,Dibwidth;
BYTE *p_data,b,g,r;
CBmpDisplayDoc *pDoc=GetDocument();
ASSERT_VALID(pDoc);
p_data=pDoc->ylpBuf ;
height=pDoc->bi.biHeight;
width=pDoc->bi.biWidth ;
Dibwidth=pDoc->Dibwidth;
LPBYTE temp1=new BYTE[height*Dibwidth];
memcpy(temp1,p_data,height*Dibwidth);
int left=pDoc->Lbpx ;
int bottom=pDoc->Lbpy ;
width=pDoc->Lbl ;
height=pDoc->Lbh;
int first=0;
int last=0;
int startx1=0;
int starty1=0;
int endx1=0;
int endy1=0;
int startx2=0;
int starty2=0;
int endx2=0;
int endy2=0;
int startx=0;
int starty=0;
int endx=0;
int endy=0;
int selectID=0;
int dl=0;
dl=80;
int hi=0;
for(int i=bottom;i<height+bottom;i++)
for(int j=left;j<left+width;j++)
{
b=temp1[i*Dibwidth+j*3];
g=temp1[i*Dibwidth+j*3+1];
r=temp1[i*Dibwidth+j*3+2];
hi=2*b-r-g;
if(hi>dl)
{
startx1=j;
starty1=i;
i=height+bottom;
j=left+width;
}
}
for(int j=left;j<left+width;j++)
for(i=bottom;i<height+bottom;i++)
{
b=temp1[i*Dibwidth+j*3];
g=temp1[i*Dibwidth+j*3+1];
r=temp1[i*Dibwidth+j*3+2];
hi=2*b-r-g;
if(hi>dl)
{
startx2=j;
starty2=i;
i=height+bottom;
j=left+width;
}
}
for( i=height+bottom;i>bottom;i--)
for( j=left+width;j>left;j--)
{
b=temp1[i*Dibwidth+j*3];
g=temp1[i*Dibwidth+j*3+1];
r=temp1[i*Dibwidth+j*3+2];
hi=2*b-r-g;
if(hi>dl)
{
endx1=j;
endy1=i;
i=bottom;
j=left;
}
}
for( j=left+width;j>left;j--)
for( i=height+bottom;i>bottom;i--)
{
b=temp1[i*Dibwidth+j*3];
g=temp1[i*Dibwidth+j*3+1];
r=temp1[i*Dibwidth+j*3+2];
hi=2*b-r-g;
if(hi>dl)
{
endx2=j;
endy2=i;
i=bottom;
j=left;
}
}
startx=startx1<startx2?startx1:startx2;
starty=starty1<starty2?starty1:starty2;
endx=endx1>endx2?endx1:endx2;
endy=endy1>endy2?endy1:endy2;
pDoc->newLbh=(endy-starty)-6;
pDoc->newLbl=(endx-startx);
int proportion=(pDoc->newLbl)/(pDoc->newLbh);
if(proportion<2)
pDoc->newLbh=pDoc->newLbl/3;
pDoc->newLbpx=startx;
pDoc->newLbpy=starty+3;
pDoc->zlpBuf=temp1;
pDoc->zflag=1;
}
void CBmpDisplayView::OnJlfg() //K--Means均值分类算法实现,k为7
{
int width,height,Dibwidth;
BYTE *p_data,b,g,r;
CBmpDisplayDoc *pDoc=GetDocument();
ASSERT_VALID(pDoc);
p_data=pDoc->ylpBuf ;
height=pDoc->bi.biHeight;//图像高度
width=pDoc->bi.biWidth ;//图像宽度
Dibwidth=pDoc->Dibwidth;//每一行图像像素
LPBYTE temp=new BYTE[height*Dibwidth];
memcpy(temp,p_data,height*Dibwidth);
int left=pDoc->newLbpx;//车牌左下角x坐标
int bottom=pDoc->newLbpy ;//车牌左下角y坐标
width=pDoc->newLbl ;//车牌宽度
height=pDoc->newLbh;//车牌高度
int oldposition[7][2];//上一次聚类中心
int newposition[7][2];//归类后的聚类中心
int classcount[7];//每类的像素个数,
int dt[7];
int dl=0;
int count=0;
for(int i=bottom;i<height+bottom;i++)//去掉车牌底色
for(int j=left;j<left+width;j++)
{
b=temp[i*Dibwidth+j*3];
g=temp[i*Dibwidth+j*3+1];
r=temp[i*Dibwidth+j*3+2];
dl=2*b-r-g;
if((dl>20)||((b-g)>20))//2*b-r-g>20 或者 b-g>20是深蓝色车牌
temp[i*Dibwidth+j*3]=temp[i*Dibwidth+j*3+1]=temp[i*Dibwidth+j*3+2]=0;//去掉底色
else
{
temp[i*Dibwidth+j*3]=temp[i*Dibwidth+j*3+1]=temp[i*Dibwidth+j*3+2]=255;
count++;
}
}
if(count==0)//如果不是深蓝色,则|g-r|>60为浅蓝色
{
for(int i=bottom;i<height+bottom;i++)
for(int j=left;j<left+width;j++)
{
b=temp[i*Dibwidth+j*3];
g=temp[i*Dibwidth+j*3+1];
r=temp[i*Dibwidth+j*3+2];
int averagecolor=(b+g+r)/3;
if(abs(g-r)>60)//|g-r|>60为浅蓝色
temp[i*Dibwidth+j*3]=temp[i*Dibwidth+j*3+1]=temp[i*Dibwidth+j*3+2]=255;//去掉底色
else
{
temp[i*Dibwidth+j*3]=temp[i*Dibwidth+j*3+1]=temp[i*Dibwidth+j*3+2]=0;
count++;
}
}
}
//以下设置7个初始点坐标
oldposition[0][0]=left+width/12;
oldposition[1][0]=oldposition[0][0]+width/6;
oldposition[2][0]=oldposition[1][0]+width/6;
for( i=3;i<7;i++)
oldposition[i][0]=oldposition[i-1][0]+2*width/15;
for( i=0;i<7;i++)
oldposition[i][1]=bottom+height/2;
//各变量赋初值
int d=0;
int nl=0;
int e=3;//收敛条件
diedai=1;//迭代次数
int flag=1;
while(flag)//迭代开始
{
for(int k=0;k<7;k++)
classcount[k]=0;//各类像素开始赋初值
for(k=0;k<7;k++)//新类中心坐标赋初值
{
newposition[k][0]=0;
newposition[k][1]=0;
}
for( i=bottom;i<height+bottom;i++)//开始扫描每个像素
for(int j=left;j<left+width;j++)
{
if(temp[i*Dibwidth+j*3]!=0)
{
for(int k=0;k<7;k++)
dt[k]=(oldposition[k][0]-j)*(oldposition[k][0]-j)
+(oldposition[k][1]-i)*(oldposition[k][1]-i);//计算当前点与每个类的中心距离
d=dt[0];
nl=0;
for(k=1;k<7;k++)//找最小值
if(d>dt[k])
{
d=dt[k];
nl=k;
}
switch(nl)//离nl类最近
{//以下先求出每类中心的坐标矢量和及及统计不同分类的像素个数,并用不同颜色表示
case 0:
newposition[0][0]=newposition[0][0]+j;//第1类中的x 坐标矢量和
newposition[0][1]=newposition[0][1]+i;//∑第1类中的y 坐标矢量和
classcount[0]++;//第1类中的像素个数
temp[i*Dibwidth+j*3]=1;//蓝色分量赋值
temp[i*Dibwidth+j*3+1]=1;//绿色分量赋值
temp[i*Dibwidth+j*3+2]=255;//红色分量赋值
break;
case 1:
newposition[1][0]=newposition[1][0]+j;
newposition[1][1]=newposition[1][1]+i;
classcount[1]++;
temp[i*Dibwidth+j*3]=255;
temp[i*Dibwidth+j*3+1]=125;
temp[i*Dibwidth+j*3+2]=0;
break;
case 2:
newposition[2][0]=newposition[2][0]+j;
newposition[2][1]=newposition[2][1]+i;
classcount[2]++;
temp[i*Dibwidth+j*3]=255;
temp[i*Dibwidth+j*3+1]=125;
temp[i*Dibwidth+j*3+2]=255;
break;
case 3:
newposition[3][0]=newposition[3][0]+j;
newposition[3][1]=newposition[3][1]+i;
classcount[3]++;
temp[i*Dibwidth+j*3]=125;
temp[i*Dibwidth+j*3+1]=125;
temp[i*Dibwidth+j*3+2]=255;
break;
case 4:
newposition[4][0]=newposition[4][0]+j;
newposition[4][1]=newposition[4][1]+i;
classcount[4]++;
temp[i*Dibwidth+j*3]=255;
temp[i*Dibwidth+j*3+1]=255;
temp[i*Dibwidth+j*3+2]=0;
break;
case 5:
newposition[5][0]=newposition[5][0]+j;
newposition[5][1]=newposition[5][1]+i;
classcount[5]++;
temp[i*Dibwidth+j*3]=255;
temp[i*Dibwidth+j*3+1]=0;
temp[i*Dibwidth+j*3+2]=125;
break;
case 6:
newposition[6][0]=newposition[6][0]+j;
newposition[6][1]=newposition[6][1]+i;
classcount[6]++;
temp[i*Dibwidth+j*3]=255;
temp[i*Dibwidth+j*3+1]=0;
temp[i*Dibwidth+j*3+2]=255;
break;
}
}
}
for(int t=0;t<7;t++)//求各类新的中心坐标
{
if(classcount[t]==0)
classcount[t]=1;
newposition[t][0]=newposition[t][0]/classcount[t];//x坐标的矢量和除以矢量个数
newposition[t][1]=newposition[t][1]/classcount[t];//y坐标的矢量和除以矢量个数
}
int subd=0;
for( t=0;t<7;t++)
{
int dt=abs(newposition[t][0]-oldposition[t][0])
+abs(newposition[t][1]-oldposition[t][1]);//求t类新的中心点与初始点中心的差距
subd=subd+dt;//∑dt
}
if(subd<=e)//迭代结束条件
flag=0;
else
{
for(t=0;t<7;t++)
{
//用新的坐标作为类的中心
oldposition[t][0]=newposition[t][0];
oldposition[t][1]=newposition[t][1];
}
diedai++;
}
}
//显示聚类效果
if(jflag)
{
pDoc->zlpBuf=temp;
pDoc->zflag=1;
pDoc->cflag=1;
jflag=false;
}
}
void CBmpDisplayView::OnCldw()
{
OnRgbtogray();//彩色转成灰度
Onjunhenghua();//均衡化
OnBianYuanJianChe();//边缘检测
OnEzbz();//二值化
OnHxqy();//检测候选区域
OnQyqd();//候选区域定位
OnJqdw();//基于纹理定位
jflag=true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -