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

📄 locategray.cpp

📁 车牌识别(改定位)武汉理工大学
💻 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 + -