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

📄 image.cpp

📁 车牌识别(改定位)武汉理工大学
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	POSITION posCurrent;
	POSITION pos;
	for(int i=0;i<nNum;i++)
	{
		pos = ptList.GetHeadPosition();
		posCurrent = pos;
		BOOL bAdd = FALSE;
		while (pos)
		{
			ptTemp = ptList.GetNext(pos);
			if (ptTemp.x==nData[i])
			{
				ptTemp.y++;
				ptList.SetAt(posCurrent,ptTemp);
				bAdd = TRUE;
				break;
			}
			else if(ptTemp.x>nData[i])
			{
				ptTemp.x = nData[i];
				ptTemp.y = 1;
				ptList.InsertBefore(posCurrent,ptTemp);
				bAdd = TRUE;
				break;
			}
			posCurrent = pos;
		}
		if (!bAdd) 
		{
			ptTemp.x = nData[i];
			ptTemp.y = 1;
			ptList.AddTail(ptTemp);
		}
	}
	pos = ptList.GetHeadPosition();
	ptMax = ptList.GetHead();
	while (pos)
	{
		ptTemp = ptList.GetNext(pos);
		if (ptMax.y<ptTemp.y)
		{
			ptMax = ptTemp;
		}
	}
	return TRUE;
}
BOOL CImage::GetLineAB(CList<CPoint,CPoint> &ptList,double &dA,double &dB)
{
	if (ptList.IsEmpty()) 
	{  
		return FALSE; 
	} 
	long lCount=ptList.GetCount(); 
	if (lCount<2) 
	{  
		return FALSE; 
	} 
	CPoint pFold; 
	double mX=0,mY=0,mXX=0,mXY=0; 
	double n;
	n = lCount; 
	double *pEr = new double[lCount];

	POSITION pos = ptList.GetHeadPosition(); 
	while (pos!=NULL) 
	{  
		pFold = ptList.GetNext(pos);  
		mX+=pFold.x;
		mY+=pFold.y;
		mXX+=pFold.x*pFold.x;        
		mXY+=pFold.x*pFold.y; 
	}    
	if(mX*mX-mXX*n==0) 
	{  
		return FALSE; 
	}   
	dA=(mY*mX-mXY*n)/(mX*mX-mXX*n);   
	dB=(mY-mX*dA)/n;  

	for(int i=0;i<lCount;i++)
	{
		pFold = ptList.GetAt(ptList.FindIndex(i));
		pEr[i] = (dA*pFold.x+dB - pFold.y)*(dA*pFold.x+dB - pFold.y);
	}
	delete []pEr;
	return TRUE;
}
BOOL CImage::Filter(CImage &imgOut, int nNeighbor,BYTE nTextVal, BYTE nBGVal)
{
	imgOut = *this;
	int sum=0;
	if (nNeighbor == 8)
	{
		for (int i=0;i<imgOut.GetHeight();i++)
		{
			for (int j=0;j<imgOut.GetWidth();j++)
			{
				sum=0;
				for (int ii = i-1;ii<=i+1;ii++)
				{
					for (int jj=j-1;jj<=j+1;jj++)
					{
						if (ii == i && jj ==j)
						{
							continue;
						}
						
                        else if (ii>=0 && ii<imgOut.GetHeight() && jj>=0 && jj<imgOut.GetWidth())
						{
							if (m_pR[ii*imgOut.GetWidth()+jj] == nTextVal)
                            {
								sum = sum+1;
							}
						}
					}
				}
				if (sum<2)
				{
					imgOut.m_pR[i*imgOut.GetWidth()+j] = nBGVal;
				}
			}
		}
	}
	else 
	{
		for (int i=0;i<imgOut.GetHeight();i++)
		{
			for (int j=0;j<imgOut.GetWidth();j++)
			{
				sum=0;
				for (int ii = i-1;ii<=i+1;ii++)
				{
					for (int jj=j-1;jj<=j+1;jj++)
					{
						if (ii == i && jj ==j || ii != i && jj !=j)
						{
							continue;
						}
						
						else if (ii>=0 && ii<imgOut.GetHeight() && jj>=0 && jj<imgOut.GetWidth())
						{
							if (m_pR[ii*imgOut.GetWidth()+jj] == nTextVal)
							{
								sum = sum+1;
							}
						}
					}
				}
				if (sum<2)
				{
					imgOut.m_pR[i*imgOut.GetWidth()+j] = nBGVal;
				}
			}
		}
	}	
	return TRUE;
}
BOOL CImage::AvgGrid(CImage &ImgOut,CSize szGrid,double * pPara)
{
	if (!ImgOut.Create(CSize(this->GetWidth(),this->GetHeight()),FALSE))
	{
		return FALSE;
	}
	long int sum;
	int sum1;
	int m,n;
	m=szGrid.cx/2;
	n=szGrid.cy/2;
	double dNum = szGrid.cx*szGrid.cy;
	for (int i=0;i<ImgOut.GetHeight();i++)
	{
		for (int j=0;j<ImgOut.GetWidth();j++)
		{
			sum=0;
			sum1=0;
			for (int ii=i-m;ii<=i+m;ii++)
			{
				for (int jj=j-n;jj<=j+n;jj++)
				{
					if (ii>=0 && ii<m_nHeight && jj>=0 && jj<m_nWidth )
						sum=sum+m_pR[ii*m_nWidth+jj];
					else
						sum1=sum1+1;
				}
			}
			ImgOut.m_pR[i*ImgOut.GetWidth()+j]=BYTE(sum/(dNum-sum1));
		}
	}
	return TRUE;
}
//以百分之多少作为域值,bReverse=FALSE时>dThreld*255时为255
BOOL CImage::Threthold(CImage &ImgOut,BYTE dThretd,BOOL bReverse)
{
	if (!ImgOut.Create(CSize(m_nWidth,m_nHeight),FALSE))
	{
		return FALSE;
	}
	int nPix = m_nWidth*m_nHeight;
	for(int i=0;i<nPix;i++)
	{
		if (bReverse)
		{
			ImgOut.m_pR[i] = (m_pR[i]>dThretd)?0:255;
		}
		else
		{
			ImgOut.m_pR[i] = m_pR[i]>dThretd?255:0;
		}
	}
	return TRUE;
}
BOOL CImage::GetChePaiRect(CImage &ImgOut,CImage &ImgGray,CList<CRect,CRect>& rcChePaiList)
{
	rcChePaiList.RemoveAll();
	if (!ImgOut.Create(CSize(m_nWidth,m_nHeight),FALSE)) 
	{
		return FALSE;
	}
	BOOL bSuceed = FALSE;
	int *pR = new int[m_nHeight];
	int *pSum = new int[m_nWidth];
	if ((!pR)||(!pSum)) {
		return FALSE;
	}
	memset(pR,0,sizeof(int)*m_nHeight);
	memset(pSum,0,sizeof(int)*m_nWidth);
	for(int i=0;i<m_nHeight;i++)
	{
		int nStart = 0;
		int nEnd = 0;
		int nRepeate = 0;
		int temp = 0;
		int start = 0;
		for(int k=0;k<m_nWidth-1;k++)
		{
			if (start==0 && m_pR[i*m_nWidth+k]==255)
			{
				nStart = k;
				nEnd = k;
				nRepeate = 1;
				start = 1;
			}
			else if (start==1 && k-nEnd<4 && m_pR[i*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<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>m_nHeight-1)
				{
					k=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)*m_nWidth);
		CPoint ptSE = ptList.GetNext(pos);
		nStart = max(ptSE.x-5,0);
		nEnd = min(ptSE.y+5,m_nHeight);
        int nStart1 =0,nEnd1=0,cishu=1;
		for(i=nStart;i<nEnd;i++)
		{
			for(int j=0;j<m_nWidth-1;j++)
			{
				if (m_pR[i*m_nWidth+j]==255)
				{
					pSum[j] += 1;
				}
			}
		}
	//	TRACE(GetIntToString(pSum,m_nWidth/2));
	//	TRACE(GetIntToString(pSum+m_nWidth/2,m_nWidth/2));
		nD = 0;
		nC = 0;
		nStart = 0;
		nEnd = 0;
		start=0;
		for(int i=0;i<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>=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,m_nHeight);
			rcTemp.left = max(nStart-5,0);
			rcTemp.right = min(nEnd,m_nWidth);
			rcTemp2.top = max(ptSE.x,0);
			rcTemp2.bottom = min(ptSE.y+5,m_nHeight);
			rcTemp2.left = max(nStart,0);
			rcTemp2.right = min(nEnd,m_nWidth);
			rcTemp4.top = min(ptSE.y+11,m_nHeight);
			rcTemp4.bottom = min(ptSE.y+13,m_nHeight);
			rcTemp4.left = max(nStart,0);
			rcTemp4.right = min(nEnd,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;
			GetAvgandS(nAvg,nS,rcTemp2);
			
			if (rcTemp.bottom == m_nHeight || rcTemp.bottom == m_nHeight-1)
			{
                rcTemp3.top = min(ptSE.x-11,m_nHeight);
				rcTemp3.bottom = min(ptSE.x-9,m_nHeight);
				rcTemp3.left = max(nStart,0);
				rcTemp3.right = min(nEnd,m_nWidth);
				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);
			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++)
					{
						ImgOut.m_pR[i*m_nWidth+j] = ImgGray.m_pR[i*m_nWidth+j];
					}
				}
                bSuceed = TRUE;
				rcChePaiList.AddTail(rcTemp);
			}
			delete []nX;
			delete []nY;
		}
	}
	
	delete []pR;
	delete []pSum;
	return bSuceed;
}
BOOL CImage::GetTiaoBian(int *nTiaoBianX, int *nTiaoBianY,CRect rcR)
{
	if (rcR.IsRectEmpty())
	{
		return FALSE;
	}
	for(int i=rcR.top;i<rcR.bottom;i++)
	{
		for(int j=rcR.left;j<rcR.right-1;j++)
		{
			if (m_pR[i*m_nWidth+j]!=m_pR[i*m_nWidth+j+1])
			{
				nTiaoBianX[i-rcR.top]++;
			}
		}
	}
    for(i=rcR.left;i<rcR.right;i++)
	{
		for(int j=rcR.top;j<rcR.bottom-1;j++)
		{
			if (m_pR[i+j*m_nWidth]!=m_pR[i+1+j*m_nWidth])
			{
				nTiaoBianY[i-rcR.left]++;
			}			
		}
	}
	return TRUE;
}
//从原图剪切出一个区域
BOOL CImage::CutFromImg(CImage &ImgOut,CRect rcImg)
{
	if (rcImg.left<0||rcImg.top<0||rcImg.right>m_nWidth||rcImg.bottom>m_nHeight)
	{
		return FALSE;
	}
	if (!ImgOut.Create(CSize(rcImg.Width(),rcImg.Height()),this->IsRGB()))
	{
		return FALSE;
	}
	for(int i=0;i<rcImg.Height();i++)
	{
		memcpy(ImgOut.m_pR+i*rcImg.Width(),m_pR+(rcImg.top+i)*m_nWidth+rcImg.left,rcImg.Width());
		if (m_bRGB)
		{
			memcpy(ImgOut.m_pG+i*rcImg.Width(),m_pG+(rcImg.top+i)*m_nWidth+rcImg.left,rcImg.Width());
			memcpy(ImgOut.m_pB+i*rcImg.Width(),m_pB+(rcImg.top+i)*m_nWidth+rcImg.left,rcImg.Width());
		}
	}
	return TRUE;
}
//细定位
/*
*	水平方向的截取是根据跳变
*	竖直方向是根据黑点个数
*	去头去未是根据最大连续点个数
*/
BOOL CImage::CutExact(CImage &ImgOut)
{
	CImage ImgTemp;
	CRect rcReal;
	int *nX = new int[m_nWidth];
	int *nTiaoBianY = new int[m_nHeight];
	memset(nTiaoBianY,0,sizeof(int)*m_nHeight);
	memset(nX,0,sizeof(int)*m_nWidth);
	
	//先去左右边界
	int i;
	rcReal.left = 0;
	rcReal.right = m_nWidth;
	rcReal.top = 0;
	rcReal.bottom = m_nHeight;
    //黑点个数,垂直方向
	for (i=0;i<m_nWidth;i++)
	{
		for (int j=0;j<m_nHeight;j++)
		{
			if(m_pR[j*m_nWidth+i]==0)
			{
				nX[i]++;
			}
		}
	}
	for (i=0;i<m_nWidth/5;i++)
	{
        if(nX[i]>0.80*m_nHeight && nX[i+1]<0.2*m_nHeight)
		{
			continue;
		}
		else
		{
			rcReal.left = i;
			break;
		}
	}
	//去掉上下边界 
	//跳变个数,水平方向
	for(i=0;i<m_nHeight;i++)
	{
		for(int j=0;j<m_nWidth-1;j++)
		{
			if (m_pR[i*m_nWidth+j]!=m_pR[i*m_nWidth+1+j])
			{
				nTiaoBianY[i]++;
			}			
		}
	}
	//	TRACE(GetIntToString(nTiaoBianY,m_nHeight));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -