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

📄 segmentationbyprojection.cpp

📁 车牌识别(改定位)武汉理工大学
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// SegmentationByProjection.cpp: implementation of the CSegmentationByProjection class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SegmentationByProjection.h"
#include "math.h"
#define ROUND(X) (((X)-int(X))>0.5?int(X)+1:int(X))

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSegmentationByProjection::CSegmentationByProjection()
{

}

CSegmentationByProjection::~CSegmentationByProjection()
{

}

BOOL CSegmentationByProjection::Segment(CList<CImage,CImage &> &ImgOutList,CImage &ImgVLP,CRect rcVLP,CImage &ImgOrg,BOOL &m_bBlack,BOOL IsEnter)
{
	CImage imTwoOrg;
	CImage imTwoQuZao;
	ImgVLP.imGraytoTwo(imTwoOrg,m_bBlack);
	CList<CRect,CRect> ListRect;
	imTwoQuZao = imTwoOrg;
	imTwoQuZao.imLTquzao(ListRect);
	double dA[2];
	double dB[2];	
	//先通过连通字符求得倾斜角
	//要是连同不行就用跳变
	if (imTwoQuZao.GetABByLianTong(dA,dB))
	{
	}
	else
	{
		ImgVLP.GetABByTioaBian(dA,dB);
	}
	//	ImgVLP.GetABByTioaBian(dA,dB);
	int nLongType = 0;//等于0为正常;等于1为太长;等于-1为太短;
	CImage imRctTwoOrg;
	CImage imRctTwoQuZao;
	CImage imRctVLP;
	ImgVLP.RectifyAB(imRctVLP,dA,dB,m_bBlack?255:0,rcVLP.TopLeft(),&ImgOrg);
	imTwoOrg.RectifyAB(imRctTwoOrg,dA,dB,m_bBlack?255:0,rcVLP.TopLeft(),NULL,FALSE);
	imTwoQuZao.RectifyAB(imRctTwoQuZao,dA,dB,m_bBlack?255:0,rcVLP.TopLeft(),NULL,FALSE);
	if (imRctVLP.GetWidth()>imRctVLP.GetHeight()*6) 
	{
		nLongType = 1;
//		AfxMessageBox("太长");
	}
	if (imRctVLP.GetWidth()<imRctVLP.GetHeight()*4) 
	{
		nLongType = -1;
	//	AfxMessageBox("太短");
	}
	//去掉左右边界
	CImage imCutTwoOrg;
	CImage imCutTwoQuZao = imRctVLP;
	CImage imCutVLP;
	CImage ImgOut;
//	ImgVLP.ShowImg();
	
	int nLR[2];	
	CImage ImgTemp2 = ImgVLP;
	ImgVLP.CutLRByTiaoBian(nLR,m_bBlack,imRctVLP.GetHeight());
	imRctVLP.CutFromImg(ImgVLP,CRect(nLR[0],0,nLR[1],imRctVLP.GetHeight()));
	imRctTwoQuZao.CutFromImg(ImgOut,CRect(nLR[0],0,nLR[1],imRctTwoQuZao.GetHeight()));
//    ImgOut.ShowImg();


	int m_nWidth = ImgVLP.GetWidth();
	int m_nHeight = ImgVLP.GetHeight();
/*
	BOOL bHaveLiangTong = TRUE;
	
	if (!bHaveLiangTong) 
	{
		if (!CutExact(ImgOut,ImgOut1)) //细定位,输出为黑字白底
		{		
			return FALSE;
		}
	}*/

	//ImgVLP.ShowImg();
//	int nLRT[2];
	return GetExactText(ImgOutList,ImgOut,ImgVLP,ImgTemp2,m_bBlack,nLR);	//传入灰度图象
	//return FALSE;
}

BOOL CSegmentationByProjection::CutExact(CImage &ImgOut, CImage &ImgIn)
{
	int m_nWidth = ImgIn.GetWidth();
	int m_nHeight = ImgIn.GetHeight();
	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(ImgIn.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 (ImgIn.m_pR[i*m_nWidth+j]!=ImgIn.m_pR[i*m_nWidth+1+j])
			{
				nTiaoBianY[i]++;
			}			
		}
	}
	//	TRACE(GetIntToString(nTiaoBianY,m_nHeight));
	
	rcReal.top = m_nHeight/2; 
	for(i=m_nHeight/2;i>=0;i--)
	{
		if (nTiaoBianY[i]<10)
		{
			rcReal.top = i+1;
			break;
		}
	}
	rcReal.top = i<=0?0:rcReal.top;
	for(i=m_nHeight/2;i<m_nHeight;i++)
	{
		if (nTiaoBianY[i]<10) 
		{
			rcReal.bottom = i;
			break;
		}
	}
	rcReal.bottom = i>=m_nHeight?m_nHeight:rcReal.bottom;
	
	//	TRACE(GetIntToString(nTiaoBianY,m_nHeight));
	
	if (rcReal.top>=rcReal.bottom) 
	{
		delete []nTiaoBianY;
		return FALSE;
	}
	delete []nX;
	delete []nTiaoBianY;
	return ImgIn.CutFromImg(ImgOut,rcReal);
}

BOOL CSegmentationByProjection::GetExactText(CList<CImage,CImage&> &ImgList,CImage &ImgIn,CImage &RImgGray,CImage &ImgGray,BOOL m_bBlack,int nLR[2])
{
//	ImgIn.ShowImg();
	int i,j;
	ImgList.RemoveAll();
	int nCalWidth[10];
	memset(nCalWidth,0,10*sizeof(int));
	CImage ImgOut,ImgOut1;
	int m_nWidth = ImgIn.GetWidth();

	ImgOut1 = ImgIn;
	CImage ImgOutLianTong;
	CList<int,int> ListNum;
	CList<CRect,CRect> ListRect;
	ImgOut1.GetLiantong(ListNum,ListRect,ImgOutLianTong,0);
	
	POSITION pos;
	POSITION pos1;
	int nIndex = ListNum.GetCount()-1;
	int nPix = ImgOut1.GetWidth()*ImgOut1.GetHeight();
	while (nIndex>=0)
	{
		pos1 = ListRect.FindIndex(nIndex);
		pos = ListNum.FindIndex(nIndex);
		int nVal = ListNum.GetAt(pos);
		BOOL bNoise = FALSE;
		if (nVal<=0)
		{
			bNoise = TRUE;
		}
		else if (nVal<5&&nVal>0)
		{
			bNoise = TRUE;
			for(i=0;i<nPix;i++)
			{
				if (ImgOutLianTong.m_pR[i]==nIndex)
				{
					ImgOut1.m_pR[i] = 255;
				}
			}
		}		
		/*	else if (nVal>=5)
		{
		CRect rcR = ListRect.GetAt(pos1);
		double dRate = ((double)nVal/((rcR.Width()+1)*(rcR.Height()+1)));
		
		  if (rcR.Height()<ImgOut1.GetHeight()*2/3||(dRate>0.9&&rcR.Width()>2))
		  {
		  bNoise = TRUE;
		  for(i=0;i<nPix;i++)
		  {
		  if (ImgOutLianTong.m_pR[i]==nIndex)
		  {
		  ImgOut1.m_pR[i] = 255;
		  }
		  }
		  }	
	}*/
		if (bNoise) 
		{
			ListRect.RemoveAt(pos1);
			ListNum.RemoveAt(pos);
		}
		nIndex--;
	}
	int nCount = ListNum.GetCount();
	ImgOut = ImgOut1;
	ImgOut1.SaveBMP("c:\\1.bmp");
	int nMaxMin[2];
	int nWidth = ImgOut.GetWidth();
	int nHeight = ImgOut.GetHeight();
/*
		if (nWidth>200) //太宽
		{
			return FALSE;
		}*/
	
	
	int *nX = new int[ImgOut.GetWidth()];//垂直方向黑点个数
	for(i=0;i<nWidth;i++)
	{
		nX[i] = 0;
		for(j=0;j<nHeight;j++)
		{
			if (ImgOut.m_pR[j*nWidth+i]==0)
			{
				nX[i]++;
			}
		}
	}
	CList<CPoint,CPoint> ptList;
	nMaxMin[0] = int(nHeight*0.7);
	nMaxMin[1] = int(nHeight*0.2);
	int nStart = -1;
	int nEnd = -1;
	
	CPoint ptTemp;
	CImage ImgTemp;
	CRect rcNead;
	CString strTempTrace = GetIntToString(nX,ImgOut.GetWidth());
	int nTraceLen = min(510,strTempTrace.GetLength());
	TRACE(strTempTrace.Mid(0,nTraceLen));
#define MAXWIDTH 25
	int nWid = nWidth/8;//字宽
	nWid = min(nWid,MAXWIDTH);
	nWid = max(nWid,5);
	for(int kk=1;kk<4;kk++)
	{
		ptList.RemoveAll();
		i = 0;
		while (i<nWidth)
		{
			if (nX[i]>=kk)
			{
				if (i==0||nStart<0)//是否该开始
				{
					nStart = i;
				}
				
				if (nStart>=0) 
				{
					if (i==nWidth-1)
					{
						ptList.AddTail(CPoint(nStart,i));
						nStart = -1;
						nEnd = -1;
					}
					else if(i-nStart>nWid+1)//寻找波谷
					{
						int nXu = nStart+2;
						int nMin = nX[nXu];
						
						for(int k=nXu;k<=i;k++)
						{
							if (nX[k]<=nMin)
							{
								nMin = nX[k];
								nXu = k;
							}
						}
						ptList.AddTail(CPoint(nStart,nXu-1));
						i = nXu;
						nStart = -1;
						nEnd = -1;
					}				
				}
			}
			else
			{
				if (i==nWidth-1||nStart>=0)
				{				
					if (i<nWidth-1)
					{
						if (i-nStart<4)//还不够长,应该往下看
						{
							BOOL bNot1 = TRUE;
							for(int k=nStart;k<=i;k++)
							{
								if (nX[k]>=nMaxMin[0])
								{
									bNot1 = FALSE;
									break;
								}
							}
							if (bNot1==FALSE) //一定是1
							{
								int nXiao = 0;//判断1的旁边是否有空位
								for(k=nStart;k<i+3;k++)
								{
									if (k>=0&&k<m_nWidth)
									{
										if (nX[k]<nMaxMin[1])
										{
											nXiao++;
										}
									}
								}
								if (nXiao>=2) 
								{
									ptList.AddTail(CPoint(nStart,i));
									nStart = -1;
									nEnd = -1;
								}							
							}
							else
							{
								if (nX[i+1]<kk) //噪音
								{

⌨️ 快捷键说明

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