📄 locategray.cpp
字号:
// LocateGray.cpp: implementation of the CLocateGray class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "LocateGray.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CLocateGray::CLocateGray()
{
}
CLocateGray::~CLocateGray()
{
}
/*
* 输入灰度图象
*/
BOOL CLocateGray::Locate(CImage& ImgVLP,CRect &rcVLP,CImage &ImgIn,int nTh)
{
//求垂直梯度
CImage ImgTemp2=ImgIn;
CImage ImgTwo,ImgOrg;
if (!ImgIn.Grad1(ImgTwo))
{
return FALSE;
}
//根据梯度将灰度图转化为二值化图
/*
CString strPath;
strPath.Format("%sconfig.sys",GetAppPath());
int nTh =GetPrivateProfileInt("ParaSet","Grad",50,strPath);*/
CImage imgTemp,imgTemp2;
imgTemp2 = ImgTwo;
if (!ImgTwo.Threthold(ImgOrg,nTh))
{
return FALSE;
}
ImgOrg.ShowImg();
CImage ImgGray;
CList<CRect,CRect> rcChePaiList;
rcChePaiList.RemoveAll();
GetChePaiHL(ImgOrg,1.2,0.15,rcChePaiList);
if (!ImgVLP.Create(CSize(ImgOrg.m_nWidth,ImgOrg.m_nHeight),FALSE))
{
return FALSE;
}
/*
BOOL bSuceed = FALSE;
int *pR = new int[ImgOrg.m_nHeight];
int *pSum = new int[ImgOrg.m_nWidth];
if ((!pR)||(!pSum)) {
return FALSE;
}
memset(pR,0,sizeof(int)*ImgOrg.m_nHeight);
memset(pSum,0,sizeof(int)*ImgOrg.m_nWidth);
for(int i=0;i<ImgOrg.m_nHeight;i++)
{
int nStart = 0;
int nEnd = 0;
int nRepeate = 0;
int temp = 0;
int start = 0;
for(int k=0;k<ImgOrg.m_nWidth-1;k++)
{
if (start==0 && ImgOrg.m_pR[i*ImgOrg.m_nWidth+k]==255)
{
nStart = k;
nEnd = k;
nRepeate = 1;
start = 1;
}
else if (start==1 && k-nEnd<4 && ImgOrg.m_pR[i*ImgOrg.m_nWidth+k]==255)
{
nEnd = k;
nRepeate ++;
}
else if (start==1 && k-nEnd>=4)
{
if (nRepeate<8)
{
start = 0;
}
else
{
if (nRepeate>temp)
{
temp = nRepeate;
pR[i] = nRepeate;
}
start = 0;
}
}
}
}
//TRACE(GetIntToString(pR,m_nHeight));
int nStart = 0;
int nEnd = 0;
int start=0;
CList<CPoint,CPoint> ptList;
int nC = 0;
int nD = 0;
int nK = 1;
int nL = 0;
while (nL<ImgOrg.m_nHeight-1)
{
if (pR[nL]>=8 && pR[nL]<40)
{
nC++;
nD = 0;
}
else
{
nD++;
}
if (nC<5&&nD>2)
{
nD = 0;
nC = 0;
}
else if ((nD>2&&nC>=5)||(nC+nD)>5)
{
for (int k=nL;k<nL+3;k++)
{
if (k>ImgOrg.m_nHeight-1)
{
k=ImgOrg.m_nHeight-1;
break;
}
if (pR[k]<8 && pR[k]>40)
{
break;
}
}
ptList.AddTail(CPoint(nL-nC-nD,k));
nL=k;
nD = 0;
nC = 0;
}
nL++;
}
POSITION pos = ptList.GetHeadPosition();
if (pos==NULL)
{
delete []pR;
delete []pSum;
return FALSE;
}
CRect rcLast(0,0,0,0);
while (pos)
{
memset(pSum,0,sizeof(int)*ImgOrg.m_nWidth);
CPoint ptSE = ptList.GetNext(pos);
nStart = max(ptSE.x-5,0);
nEnd = min(ptSE.y+5,ImgOrg.m_nHeight);
int nStart1 =0,nEnd1=0,cishu=1;
for(i=nStart;i<nEnd;i++)
{
for(int j=0;j<ImgOrg.m_nWidth-1;j++)
{
if (ImgOrg.m_pR[i*ImgOrg.m_nWidth+j]==255)
{
pSum[j] += 1;
}
}
}
// TRACE(GetIntToString(pSum,ImgOrg.m_nWidth/2));
// TRACE(GetIntToString(pSum+ImgOrg.m_nWidth/2,ImgOrg.m_nWidth/2));
nD = 0;
nC = 0;
nStart = 0;
nEnd = 0;
start=0;
for(int i=0;i<ImgOrg.m_nWidth-1;i++)
{
if (pSum[i]>=3 && start==0)
{
nStart = i;
nD = 0;
start = 1;
nC = 1;
}
else if (pSum[i]>=3 && start==1)
{
nD = 0;
nC ++;
}
else if (pSum[i]<3 && start==1)
{
nD++;
}
if (nD>6 && start==1 && nC<=20)
{
start = 0;
nC = 0;
nD = 0;
}
else if (nD>6 && start==1 && nC>20)
{
nEnd = i;
if (nStart<15)
{
start = 0;
nStart = i;
}
else if(cishu==1)
{
nStart1 = nStart;
nEnd1 = nEnd;
cishu++;
start =0;
nStart = i;
}
else
{
break;
}
}
else if (nD<=6 && nC>20 && i>=ImgOrg.m_nWidth-2)
{
nEnd = i;
if (nStart<15)
{
start = 0;
nStart = i;
}
else
{
break;
}
}
}
if ((nEnd1-nStart1)>(nEnd-nStart))
{
nStart = nStart1;
nEnd = nEnd1;
}
if (nStart<nEnd)
{
CRect rcTemp,rcTemp1,rcTemp2,rcTemp3,rcTemp4;
CRect rcOut(0,0,0,0);
rcTemp.top = max(ptSE.x-5,0);
rcTemp.bottom = min(ptSE.y+10,ImgOrg.m_nHeight);
rcTemp.left = max(nStart-5,0);
rcTemp.right = min(nEnd,ImgOrg.m_nWidth);
rcTemp2.top = max(ptSE.x,0);
rcTemp2.bottom = min(ptSE.y+5,ImgOrg.m_nHeight);
rcTemp2.left = max(nStart,0);
rcTemp2.right = min(nEnd,ImgOrg.m_nWidth);
rcTemp4.top = min(ptSE.y+11,ImgOrg.m_nHeight);
rcTemp4.bottom = min(ptSE.y+13,ImgOrg.m_nHeight);
rcTemp4.left = max(nStart,0);
rcTemp4.right = min(nEnd,ImgOrg.m_nWidth);
BOOL IsChePai = TRUE;
int dis = rcTemp4.right-rcTemp4.left+1;
int *nX = new int[3];
int *nY = new int[dis];
memset(nX,0,sizeof(int)*3);
memset(nY,0,sizeof(int)*dis);
if (GetOvlap(rcOut,rcTemp,rcLast))//有重叠
{
CRect rcTT = rcTemp;
if (rcOut.Width()>1&&rcOut.Height()>1) //要合并
{
rcTemp.top = min(rcTemp.top,rcLast.top);
rcTemp.left = min(rcTemp.left,rcLast.left);
rcTemp.right = max(rcTemp.right,rcLast.right);
rcTemp.bottom = max(rcTemp.bottom,rcLast.bottom);
}
if (rcTemp.Width()>120||rcTemp.Height()>45)
{
rcTemp = rcTT;
}
}
rcLast = rcTemp;
int nAvg =0 ,nS =0;
ImgOrg.GetAvgandS(nAvg,nS,rcTemp2);
if (rcTemp.bottom == ImgOrg.m_nHeight || rcTemp.bottom == ImgOrg.m_nHeight-1)
{
rcTemp3.top = min(ptSE.x-11,ImgOrg.m_nHeight);
rcTemp3.bottom = min(ptSE.x-9,ImgOrg.m_nHeight);
rcTemp3.left = max(nStart,0);
rcTemp3.right = min(nEnd,ImgOrg.m_nWidth);
ImgOrg.GetTextPointNum(nX,nY,rcTemp3,255);
for (i=0; i<2;i++)
{
if (nX[i]>=0.2*nAvg)
{
IsChePai = FALSE;
break;
}
}
}
memset(nX,0,sizeof(int)*3);
memset(nY,0,sizeof(int)*dis);
ImgOrg.GetTextPointNum(nX,nY,rcTemp4,255);
for (i=0 ; i<2;i++)
{
if (nX[i]>=0.8*nAvg)
{
IsChePai = FALSE;
break;
}
}
double dR;
dR=(double)rcTemp.Width()/rcTemp.Height();
if (dR>1.5 && dR<5 && rcTemp.Width()>45 && nAvg>=18 && IsChePai && rcTemp.Height()<35)
{
for(i=rcTemp.top;i<rcTemp.bottom;i++)
{
for(int j=rcTemp.left;j<rcTemp.right;j++)
{
ImgVLP.m_pR[i*ImgOrg.m_nWidth+j] = ImgOrg.m_pR[i*ImgOrg.m_nWidth+j];
}
}
bSuceed = TRUE;
rcChePaiList.AddTail(rcTemp);
}
delete []nX;
delete []nY;
}
}*/
if(rcChePaiList.GetCount()==0)
{
Locate(ImgVLP,rcVLP,imgTemp2,20);
}
else
{
rcVLP = rcChePaiList.GetTail();
for(int i=rcVLP.top;i<rcVLP.bottom;i++)
{
for(int j=rcVLP.left;j<rcVLP.right;j++)
{
ImgVLP.m_pR[i*ImgOrg.m_nWidth+j] = ImgOrg.m_pR[i*ImgOrg.m_nWidth+j];
}
}
}
return TRUE;
}
/*
返回二值化图像中车牌区域的行,列大致范围。
参数a,b可以调节列的范围,一般为a=1.5,b=0.15——a,b越大显示的区域越大*/
BOOL CLocateGray::GetChePaiHL(CImage ImgIn,double a, double b,CList<CRect,CRect> &rcChePaiList)
{
int Height=ImgIn.m_nHeight;
int Width=ImgIn.m_nWidth;
int *pR = new int[Height];
int *pSum = new int[Width];
if ((!pR)||(!pSum)) {
return FALSE;
}
memset(pR,0,sizeof(int)*Height);
memset(pSum,0,sizeof(int)*Width);
for(int i=0;i<Height;i++)
{
int nStart = 0;
int nRepeate = 0;
for(int j=0;j<Width-1;j++)
{
if(ImgIn.m_pR[i*Width+j]>0)
{
while(ImgIn.m_pR[i*Width+j+1]>0 && j<Width-1)
{
j=j+1;
}
if(j-nStart>25 && nRepeate<8)
{
nRepeate=0;
}
nRepeate++;
nStart=j;
}
}
if(nRepeate<8)
{
for(j=0;j<Width;j++)
{
ImgIn.m_pR[i*Width+j]=0;
pR[i]=0;
}
}
else
{
pR[i]=1;
}
}
int nE = 0;
int nB = 0;
int nK = 1;
int nL = 0;
CList<CPoint,CPoint> ptList;
for(i=0;i<Height;i++)
{
if(pR[i]==1)
{
nE=i;
if(i-nK>3||i<3)
{
nE = nK;
ptList.AddTail(CPoint(nB,nE));
nB = i;
nE = i;
}
nK=i;
}
}
//上述代码会导致最后一次没加,这里补上
if(nE-nB>8)
{
ptList.AddTail(CPoint(nB,nE));
}
POSITION pos = ptList.GetTailPosition();
if (pos==NULL)
{
delete []pR;
delete []pSum;
return FALSE;
}
CRect rcLast(0,0,0,0);
CPoint ptSE = ptList.GetPrev(pos);
while(ptSE.y-ptSE.x<10 && ptList.GetCount()>2)
{
ptList.RemoveTail();
pos = ptList.GetTailPosition();
ptSE = ptList.GetPrev(pos);
}
pos = ptList.GetTailPosition();
ptSE = ptList.GetPrev(pos);
//确定行列范围
int nStart = max(ptSE.x-7,0);
int nEnd = min(ptSE.y+7,Height);
memset(pSum,0,sizeof(int)*Width);
for(i=nStart;i<nEnd;i++)
{
for(int j=0;j<Width;j++)
{
if (ImgIn.m_pR[i*Width+j]==255)
{
pSum[j] += 1;
}
}
}
int wb=0;
int we=0;
int k=0;
int num_pix=0;
for(i=nStart;i<nEnd;i++)
{
for(int j=1;j<Width-1;j++)
{
if (ImgIn.m_pR[i*Width+j]==255)
{
num_pix++;
}
}
}
//w_u的确定有问题
double w_c=a*(nEnd-nStart);
double w_u=0.15*num_pix/(nEnd-nStart);
int wn=0;
for(i=0;i<Width;i++)
{
if(pSum[i]>w_u)
{
if(i-k>w_c)
{
if(wn>w_c)
{
break;
}
else
{
wn=0;
wb=i;
we=i;
k=i;
}
}
else
{
wn=i-wb;
we=i;
k=i;
}
}
}
if(wb>4)
{
wb=wb-3;
}
if(we<Width-3)
{
we=we+3;
}
if(wb==0)
{
wb=wb+1;
}
else if(we==Width)
{
we=we-1;
}
CRect rcTemp;
rcTemp.top = nStart;
rcTemp.bottom = nEnd;
rcTemp.left = wb;
rcTemp.right = we;
rcChePaiList.AddTail(rcTemp);
delete[]pR;
delete[]pSum;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -