📄 reconizedlg.cpp
字号:
bool Isexist=false;
pointX1=0;pointY1=0;pointX2=0;pointY2;
for(right=col-1;right>0;right--)
for(left=0;Isexist==false&&left<right;left++) //选择两列作为车牌垂直边
{
if(abs(Ltopi[left]-Ltopi[right])>40&&abs(Ltopi[left]-Ltopi[right])<160 //满足相隔一定距离与(基本是矩形)
&&abs(Ltopj[left]-Ltopj[right])<2&&abs(Rlowj[left]-Rlowj[right])<2 //对齐
&&(float)abs(Ltopi[left]-Ltopi[right])/(float)(abs(Ltopj[left]-Rlowj[left]))>2.0&&
(float)abs(Ltopi[left]-Ltopi[right])/(float)(abs(Ltopj[left]-Rlowj[left])<3.5) ) // 满足长宽比例在[1,3]之间
{
pointX1=Ltopi[left];pointY1=Ltopj[left];
pointX2=Rlowi[right];pointY2=Rlowj[right];
if(pointX1>pointX2)
{
pointX2=Ltopi[left];pointY2=Ltopj[left];
pointX1=Rlowi[right];pointY1=Rlowj[right];
}
Isexist=true;
break;
}
}
//////////////////////////////////////////
CClientDC dc(this);
for(i=0;i<m_Width;i++) //rgb
for(j=0;j<m_Height;j++)
{
//dc.SetPixel(i+1,j+1,RGB(Buffer[i][j][2],Buffer[i][j][1],Buffer[i][j][0]) );
dc.SetPixel(i+1,j+1,RGB(Buffer1[i][j],Buffer1[i][j],Buffer1[i][j]) );
}
for(col=0;col<50&&Ltopi[col]>0;col++)
for(j=Ltopj[col];j<Rlowj[col];j++)
{
dc.SetPixel(Ltopi[col]+2,j+2,RGB(0,255,0) );
}
for(i=pointX1;i<pointX2;i++) // 划水平线
{
dc.SetPixel(i+1,pointY1+1,RGB(255,0,0));
dc.SetPixel(i+1,pointY2+1,RGB(255,0,0));
}
for(j=pointY1;j<pointY2;j++) //画垂直线
{
dc.SetPixel(pointX1+1,j+1,RGB(255,0,0));
dc.SetPixel(pointX2+1,j+1,RGB(255,0,0));
}
}
void CReconizeDlg::OnDrawRect() //标出车牌
{
// TODO: Add your control notification handler code here
CClientDC dc(this);
for(int i=pointX1-2;i<pointX2+2;i++) //
for(int j=pointY1-2;j<pointY2+2;j++)
{
dc.SetPixel(i-pointX1+20,j-pointY1+350,RGB(Buffer[i][j][2],Buffer[i][j][1],Buffer[i][j][0]));
}
}
void CReconizeDlg::OnQuickReconize()
{
// TODO: Add your control notification handler code here
if(Flag!=0)
{
MessageBox("未打开图象","除错",MB_ICONSTOP|MB_OK);
return;
}
OnToGray(); //求出灰度图
OnWhiteBlack();//求出二值图
OnDrawEdge();//描点
OnDrawRect(); //求出平均矩形
MessageBox("刘海锋----2006--11--20");
}
void CReconizeDlg::DrawRect() //绘制矩形。
{
// TODO: Add your command handler code here
MatchRect2();
CString tmpStr1;
tmpStr1.Format("矩形总数: %d",indexRect);
MessageBox(tmpStr1);
CClientDC dc(this);
//OnDrawOrig();
CPen pen(PS_SOLID,1,RGB(255,0,0));
dc.SelectObject(pen);
int i;
for(i=0;i<indexRect;i++)
{
dc.MoveTo( PointLT[Rect[i][0]][0] , PointLT[Rect[i][0]][1] );///////
dc.LineTo( PointRT[Rect[i][1]][0] , PointRT[Rect[i][1]][1] );
dc.MoveTo( PointRT[Rect[i][1]][0] , PointRT[Rect[i][1]][1] );
dc.LineTo( PointRB[Rect[i][2]][0] , PointRB[Rect[i][2]][1] );
dc.MoveTo( PointRB[Rect[i][2]][0] , PointRB[Rect[i][2]][1] );
dc.LineTo( PointLB[Rect[i][3]][0] , PointLB[Rect[i][3]][1] );
dc.MoveTo( PointLB[Rect[i][3]][0] , PointLB[Rect[i][3]][1] );
dc.LineTo( PointLT[Rect[i][0]][0] , PointLT[Rect[i][0]][1] );
}
}
void CReconizeDlg::MatchRect2()
{
indexRect=0;
int i,j,k,l;
for(i=0;i<50000;i++)
for(j=0;j<4;j++)
Rect[i][j]=-1;
////////////i PointLT ; j PointRT ; k PointRB ; l PointLB
double x,y,rate, x1,y1,rate1;
for(i=0;i<index1;i++)
{
Rect[indexRect][0]=i;
for(j=0;j<index2;j++)
{
if( PointRT[j][0]>(PointLT[i][0]+80) && abs(PointRT[j][1]-PointLT[i][1])<10 )//符合要求的右上点
{
for(k=0;k<index3;k++)
{
if( abs(PointRB[k][0]-PointRT[j][0])<10 && PointRB[k][1]>(PointRT[j][1]+40) )//符合要求的右下点
{
for(l=0;l<index4;l++)
{
if( PointLB[l][0]<PointRB[k][0]-80 && abs(PointLB[l][1]-PointRB[k][1])<10
&& abs(PointLB[l][0]-PointLT[i][0])<10 && PointLB[l][1]>PointLT[i][1]+40 )//符合要求的左下点
{
x = PointRT[j][0]-PointLT[i][0];
y = PointRB[k][1]-PointRT[j][1]+0.001;
x1= PointRB[k][0]-PointLB[l][0];
y1= PointLB[l][1]-PointLT[i][1]+0.001;
rate = x/y;
rate1= x1/y1;
if(rate>=2.7 && rate<=3.3 && rate1>=2.7 && rate1<=3.3)
{
Rect[indexRect][0]=i;
Rect[indexRect][1]=j;
Rect[indexRect][2]=k;
Rect[indexRect][3]=l;
indexRect++;
}
}
}//for(l=0;l<index4;l++)
}
}//for(k=0;k<index3;k++)
}
}//for(j=0;j<index2;j++)
}//for(i=0;i<index1;i++)
}
void CReconizeDlg::DrawAvgrect() //求出平均矩形。
{
// TODO: Add your command handler code here
AvgRect();
DrawBMP();
CString tmpStr1;
tmpStr1.Format(" 车牌: %d",avgindexRect);
MessageBox(tmpStr1);
CClientDC dc(this);
CPen pen(PS_SOLID,1,RGB(255,0,0));
dc.SelectObject(pen);
DrawBMP();
int i;
for(i=0;i<avgindexRect;i++)
{
dc.MoveTo( avgPointLT[i][0] , avgPointLT[i][1] );
dc.LineTo( avgPointRT[i][0] , avgPointRT[i][1] );
dc.MoveTo( avgPointRT[i][0] , avgPointRT[i][1] );
dc.LineTo( avgPointRB[i][0] , avgPointRB[i][1] );
dc.MoveTo( avgPointRB[i][0] , avgPointRB[i][1] );
dc.LineTo( avgPointLB[i][0] , avgPointLB[i][1] );
dc.MoveTo( avgPointLB[i][0] , avgPointLB[i][1] );
dc.LineTo( avgPointLT[i][0] , avgPointLT[i][1] );
}
}
bool CReconizeDlg::MatchRectPoint(int i,int j)
{ int Distance,k; //两个矩形的顶点相距参数
bool flag=true;
Distance=25;
for(k=0;flag&&k<2;k++)
if(abs(PointLT[Rect[i][0]][k]-PointLT[Rect[j][0]][k])<=Distance
&&abs(PointRT[Rect[i][1]][k]-PointRT[Rect[j][1]][k])<=Distance
&&abs(PointRB[Rect[i][2]][k]-PointRB[Rect[j][2]][k])<=Distance
&&abs(PointLB[Rect[i][3]][k]-PointLB[Rect[j][3]][k])<=Distance
)
flag=true;
else flag=false;
return(flag);
}
void CReconizeDlg::AvgRect()
{
bool AlreadyRect[50000];
int i,j,k,count,tempLT[2],tempRT[2],tempRB[2],tempLB[2];
avgindexRect=0;
for(i=0;i<2;i++)
{
tempLT[i]=0;
tempLB[i]=0;
tempRT[i]=0;
tempRB[i]=0;
}
for( i=0;i<50000;i++)
{
AlreadyRect[i]=false;
}
for( i=0;i<indexRect;i++)
{
if(!AlreadyRect[i])
{
count=1;
for(k=0;k<2;k++)
{
tempLT[k]=PointLT[Rect[i][0]][k];
tempLB[k]=PointLB[Rect[i][3]][k];
tempRT[k]=PointRT[Rect[i][1]][k];
tempRB[k]=PointRB[Rect[i][2]][k];
}
for(j=i+1;j<indexRect;j++)
{
if(!AlreadyRect[j])
if(MatchRectPoint(i,j))
{
AlreadyRect[i]=true;
AlreadyRect[j]=true;
count++;
for(k=0;k<2;k++)
{
tempLT[k]+=PointLT[Rect[j][0]][k];
tempLB[k]+=PointLB[Rect[j][3]][k];
tempRT[k]+=PointRT[Rect[j][1]][k];
tempRB[k]+=PointRB[Rect[j][2]][k];
}
}
}
for(k=0;k<2;k++)
{
avgPointLT[avgindexRect][k]=int(tempLT[k]/(count*1.0));
avgPointRT[avgindexRect][k]=int(tempRT[k]/(count*1.0));
avgPointRB[avgindexRect][k]=int(tempRB[k]/(count*1.0));
avgPointLB[avgindexRect][k]=int(tempLB[k]/(count*1.0));
}
avgindexRect++;//找到矩形个数
}
}
}
int CReconizeDlg::PickColor(int index)
{
int i,j,blueNum,whiteNum,blackNum,yellowNum,allNum;
blueNum=0;
blackNum=0;
yellowNum=0;
whiteNum=0;
for(i= (HaveJumpRectLT[index][0]+HaveJumpRectLB[index][0]) /2 ;
i< (HaveJumpRectRT[index][0]+HaveJumpRectRB[index][0]) /2;
i++)
for(j=(HaveJumpRectLT[index][1]+HaveJumpRectRT[index][1])/2;
j=(HaveJumpRectLB[index][1]+HaveJumpRectRB[index][1])/2;
j++)
{
if(2*Buffer[i][j][0]-Buffer[i][j][1]-Buffer[i][j][2]>0)
blueNum++;
if((Buffer[i][j][0]>=200)
&&(Buffer[i][j][0]>=200)
&&(Buffer[i][j][0]>=200)
&&(abs(Buffer[i][j][0]-Buffer[i][j][1])<25)
&&(abs(Buffer[i][j][0]-Buffer[i][j][2])<25)
&&(abs(Buffer[i][j][1]-Buffer[i][j][2])<25)
)
whiteNum++;
if( (Buffer[i][j][2]+Buffer[i][j][1]-2*Buffer[i][j][0])>0
&& ( abs(Buffer[i][j][2]-Buffer[i][j][1])<20) )
yellowNum++;
if( (Buffer[i][j][0]<=55)
&&(Buffer[i][j][0]<=55)
&&(Buffer[i][j][0]>=55)
&&(abs(Buffer[i][j][0]-Buffer[i][j][1])<25)
&&(abs(Buffer[i][j][0]-Buffer[i][j][2])<25)
&&(abs(Buffer[i][j][1]-Buffer[i][j][2])<25)
)
blackNum++;
}
allNum=i*j;
if( (blueNum/ (1.0*allNum) >0.5) && (whiteNum/(1.0*allNum)>0.1) )
return 1;
if((yellowNum/ (1.0*allNum) >0.5) && (blackNum/(1.0*allNum)>0.1))
return 2;
if((blackNum/ (1.0*allNum) >0.5) && (whiteNum/(1.0*allNum)>0.1))
return 3;
if((whiteNum/ (1.0*allNum) >0.5) && (blackNum/(1.0*allNum)>0.1))
return 4;
return 5;
}
void CReconizeDlg::drawXYchou()
{
int i,j;
CClientDC dc(this);
for(i=25;i<26;i++) //rgb 画Y轴
for(j=700;j>400;j--)
{
dc.SetPixel(i,j,RGB(200,0,0) );
}
for(j=700;j<701;j++)
for(i=25;i<420;i++) //rgb 画X轴
{
if(((i+1-25)%10)==1) //在10的整数倍点标记
{
dc.SetPixel(i+1,j,RGB(0,0,0) );dc.SetPixel(i+1,j-1,RGB(0,0,0) );dc.SetPixel(i+1,j+1,RGB(0,0,0) );
if(((i+1-25)%50)==1) //在50的整数倍点标记
{
dc.SetPixel(i+1,j+2,RGB(0,0,0) );
dc.SetPixel(i+1,j+3,RGB(0,0,0) );
dc.SetPixel(i+1,j+4,RGB(0,0,0) );
}
}
else
dc.SetPixel(i+1,j,RGB(200,0,0) );
}
}
void CReconizeDlg::Onhuidujunheng() //灰度分布均衡化
{
// TODO: Add your control notification handler code here
int i,j;
float tongji[256],huidu[256];
float temp_r[256]; //中间变量
int nNs_R[256];
for(i=0;i<256;i++) //初始化
{
huidu[i]=0;
tongji[i]=0;
temp_r[i]=0;
}
GetGrayBmp();
CClientDC dc(this);
for(i=0;i<m_Width;i++) //rgb
for(j=0;j<m_Height;j++)
{
dc.SetPixel(i+1,j+1,RGB(Buffer1[i][j],Buffer1[i][j],Buffer1[i][j]) );
huidu[Buffer1[i][j]]++;//统计灰度
}
//下面是均衡化处理
for(i=0;i<256;i++)
tongji[i]=huidu[i]/(m_Width*m_Height*1.0f);
for(i=0;i<256;i++)
{
if(i==0)
{
temp_r[0]=(float)tongji[0];
}
else
{
temp_r[i]=temp_r[i-1]+tongji[i];
}
nNs_R[i]=(int)(255.0f*temp_r[i]+0.5f);
}
//对各象数进行灰度转换
for(i=0;i<m_Width;i++) //rgb
for(j=0;j<m_Height;j++)
{
Buffer1[i][j]=nNs_R[Buffer1[i][j]];
}
for(i=0;i<256;i++) //初始化
{
huidu[i]=0;
}
for(i=0;i<m_Width;i++) //rgb
for(j=0;j<m_Height;j++)
{
// dc.SetPixel(i+1,j+1,RGB(255,255,255) );
dc.SetPixel(i+1,j+1,RGB(Buffer1[i][j],Buffer1[i][j],Buffer1[i][j]) );
huidu[Buffer1[i][j]]++;//统计灰度
}
drawzhifatu(); //对当前图象画直方图
}
void CReconizeDlg::OnSobelCheck()
{
// TODO: Add your control notification handler code here
int i=0,j=0;
int Temp_i=0,Temp_j=0;//临时变量
// int temp1[3][3]={-1,-2,-1,0,0,0,1,2,3};//水平模板
// int temp2[3][3]={1,0,-1,2,0,-2,1,0,-1};//垂直模板
int TempBuff1[500][500];
// int TempBuff2[1024][1024];
for(i=0;i<500;i++)
for(j=0;j<500;j++)
{
TempBuff1[i][j]=0;
// TempBuff2[i][j]=0;
}
for(i=1;i<m_Width-1;i++) //做卷积 ,边缘不做
for(j=1;j<m_Height-1;j++)
{
Temp_i=abs(Buffer1[i-1][j+1]+2*Buffer1[i][j+1]+Buffer1[i+1][j+1]-Buffer1[i-1][j-1]-2*Buffer1[i][j-1]-Buffer1[i-1][j-1]);
Temp_j=abs(Buffer1[i-1][j-1]+2*Buffer1[i-1][j]+Buffer1[i-1][j+1]-Buffer1[i+1][j-1]-2*Buffer1[i+1][j]-Buffer1[i+1][j+1]);
/* if(Temp_i>255)
Temp_i=255;
if(Temp_j>255)
Temp_j=255;
if(Temp_i>Temp_j) //把灰度较大的保存
TempBuff1[i][j]=Temp_i;
else
TempBuff1[i][j]=Temp_j;
*/
TempBuff1[i][j]=(int)(sqrt(Temp_j*Temp_j+Temp_i*Temp_i));
if(TempBuff1[i][j]>255)
TempBuff1[i][j]=255;
}
for(i=1;i<m_Width-1;i++) //复制处理后的图象象数
for(j=1;j<m_Height-1;j++)
{
Buffer1[i][j]=TempBuff1[i][j];
}
CClientDC dc(this);
for(i=0;i<m_Width;i++) //rgb
for(j=0;j<m_Height;j++)
{
dc.SetPixel(i+1,j+1,RGB(Buffer1[i][j],Buffer1[i][j],Buffer1[i][j]) );
}
drawzhifatu();
// delete []TempBuff1;
}
void CReconizeDlg::drawzhifatu() //对当前图象画直方图
{
int i,j;
int huidu[256];
for(i=0;i<256;i++)
huidu[i]=0;
CClientDC dc(this);
for(i=0;i<m_Width;i++) //rgb
for(j=0;j<m_Height;j++)
{
huidu[Buffer1[i][j]]++;//统计灰度
}
for(i=0;i<256;i++) // 在坐标轴画直方图初始化
for(j=700;j>400;j--)
dc.SetPixel(i+26,j,RGB(255,255,255));
for(i=0;i<256;i++) // 在坐标轴画直方图
for(j=700;(j>700-huidu[i]/6)&&j>400;j--)
dc.SetPixel(i+26,j,RGB(50,50,50));
}
void CReconizeDlg::OnYawpDrop() //除去噪声
{
int i,j,Temp_i=0;
int TempBuff2[500][500];
for(i=0;i<500;i++)
for(j=0;j<500;j++)
{
TempBuff2[i][j]=0;
}
int mid_temp=0,mid[9];
for(int m=0;m<9;m++)
mid[m]=0;
for(i=1;i<m_Width-1;i++) //中值滤波 ,边缘不做
for(j=1;j<m_Height-1;j++)
{
// Temp_i=abs(Buffer1[i-1][j-1]+2*Buffer1[i][j-1]+Buffer1[i+1][j-1]+Buffer1[i-1][j]+4*Buffer1[i][j]+2*Buffer1[i+1][j]
// +Buffer1[i-1][j+1]+2*Buffer1[i][j+1]+Buffer1[i+1][j+1]);
// Temp_i=(int)(Temp_i*1.0/16.0+0.5f);
mid[0]=Buffer1[i-1][j-1]; mid[1]=Buffer1[i][j-1]; mid[2]=Buffer1[i+1][j-1];
mid[3]=Buffer1[i-1][j]; mid[4]=Buffer1[i][j]; mid[5]=Buffer1[i+1][j];
mid[6]=Buffer1[i-1][j+1]; mid[7]=Buffer1[i][j+1]; mid[8]=Buffer1[i+1][j+1];
for(int m=0;m<9;m++) //排序
for(int n=0;n<=m-1;n++)
{
if(mid[m]>mid[n]){mid_temp=mid[n];mid[n]=mid[m];mid[m]=mid_temp;}
}
Temp_i=mid[4]; //中值
if(Temp_i>255)
Temp_i=255;
TempBuff2[i][j]=Temp_i;
}
for(i=1;i<m_Width-1;i++) //复制处理后的图象象数
for(j=1;j<m_Height-1;j++)
{
Buffer1[i][j]=TempBuff2[i][j];
}
CClientDC dc(this);
for(i=0;i<m_Width;i++) //rgb
for(j=0;j<m_Height;j++)
{
dc.SetPixel(i+1,j+1,RGB(Buffer1[i][j],Buffer1[i][j],Buffer1[i][j]) );
}
drawzhifatu();
// delete []TempBuff2;
}
bool CReconizeDlg::IsMatch(int i, int j) //判断Buffer1[i][j]点右边与下面是否可能为车牌边缘
{
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -