⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bmpdisplayview.cpp

📁 用VC编写的基于K-means的车牌识别程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	  }

	  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 + -