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

📄 lprprocess.cpp

📁 TRY2LPR-1.0开源的车牌识别核心
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*
* Copyright (c) 2003, try2it.com
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
* 
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
* 
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* 文件名称:LPRHelper.cpp
* 文件标识:LPR-02-05
* 摘要:牌照识别的图像处理部分
*
* 当前版本:1.0
* 作者:try2it.com
* 开始日期:2003年09月28日
* 完成日期:2003年09月30日
*/
#include "stdafx.h"
#include <malloc.h>
#include <math.h>
#include <stdio.h>
#include <io.h>
#include "../include/types.h"
#include "LPRHelper.h"
#include "LPRProcess.h"

/*------------------------------------------------------------------
* 以下声明全局变量
------------------------------------------------------------------*/
int g_LPHeight = 80;       
int g_LPWidth = 220;     
int g_LPAccurateHeight = 40; 
int g_BYDiff = 10;        
int g_BWDiff = 20;       
int g_BlackLP = 80;       
int g_WhiteLP = 220;      
int g_BYLP = 60;         
int g_Threshold = 160;    
int g_Threshold_HLP = 100; 
int g_LeftOffset = 0;      
int g_RightOffset = 0;    
int g_TopOffset = 0;       
int g_BottomOffset = 0;  

int InteEqualize(PGrayImg pDestImg, PGrayImg pSrcImg)
{
	int res = 0;
	int HistoGram[256];
	int bMap[256];

	int Temp, i, j;
	TGrayImg TempImg;

	res = CalHistoGram(HistoGram, pSrcImg);
	if (res == 0)
		return 0;

	res = GrayImg_Malloc(&TempImg, pSrcImg->Width, pSrcImg->Height);
	if (res == 0)
		return 0;
	
    for (i=0; i<256; i++)
    {
		Temp = 0;
        for (j=0; j<=i; j++)
			Temp = Temp + HistoGram[j];

        bMap[i] = (int)(Temp*255.0/pSrcImg->Height/pSrcImg->Width+0.5);
	}

    for (i=0; i<pSrcImg->Height; i++)
		for (j=0; j<pSrcImg->Width; j++)
        {
			*(TempImg.pImg+i*TempImg.Width+j) = (BYTE)bMap[*(pSrcImg->pImg+i*pSrcImg->Width+j)];
		}

	pDestImg->Width = TempImg.Width;
	pDestImg->Height = TempImg.Height;

	if (pDestImg->pImg) 
	{
		pDestImg->pImg = NULL;
	}

	pDestImg->pImg = TempImg.pImg;

	return res;
}

int CalHistoGram(int HistoGram[], PGrayImg pSrcImg)
{
	int i, j;
	
	for (i=0; i<256; i++) HistoGram[i] = 0;

	for (i=0; i<pSrcImg->Height; i++)
		for (j=0; j<pSrcImg->Width; j++)
			HistoGram[*(pSrcImg->pImg+i*pSrcImg->Width+j)]++;

	return 1;
}

int MedianFilter(PGrayImg pDestImg, PGrayImg pSrcImg, int iFilterH, 
				               int iFilterW, int iFilterMX, int iFilterMY)
{
	int i, j, l, k;
	int res = 0;
	BYTE *aValue;

	TGrayImg TempImg;

	res = GrayImg_Malloc(&TempImg, pSrcImg->Width, pSrcImg->Height);
	if (res == 0)
		return 0;

	aValue = (BYTE*)malloc(iFilterH * iFilterW);
	if (aValue == NULL)
		return 0;

	for (i=iFilterMY; i<=TempImg.Height-iFilterH+iFilterMY; i++)
		for (j=iFilterMX; j<=TempImg.Width-iFilterW+iFilterMX; j++)
		{
			for (k=0; k<iFilterH; k++)
				for (l=0; l<iFilterW; l++)
				{
					*(aValue+k*iFilterW+l) = *(pSrcImg->pImg+(i-iFilterMY+k)*TempImg.Width+j-iFilterMX+1);
				}
			*(TempImg.pImg+i*TempImg.Width+j) = GetMedianNum(aValue, iFilterH*iFilterW);
		}

	if (aValue!=NULL)
		free(aValue);

	for (i=0; i<TempImg.Height; i++)
		for (j=0; j<iFilterMX; j++)
			*(TempImg.pImg+i*TempImg.Width+j) = *(pSrcImg->pImg+i*pSrcImg->Width+j);

	for (i=0; i<TempImg.Height; i++)
		for (j=TempImg.Width-iFilterW+iFilterMX+1; j<TempImg.Width; j++)
			*(TempImg.pImg+i*TempImg.Width+j) = *(pSrcImg->pImg+i*pSrcImg->Width+j);

	for (i=0; i<iFilterMY; i++)
		for (j=0; j<TempImg.Width; j++)
			*(TempImg.pImg+i*TempImg.Width+j) = *(pSrcImg->pImg+i*pSrcImg->Width+j);

	for (i=TempImg.Height-iFilterH+iFilterMY+1; i<TempImg.Height; i++)
		for (j=0; j<TempImg.Width; j++)
			*(TempImg.pImg+i*TempImg.Width+j) = *(pSrcImg->pImg+i*pSrcImg->Width+j);

	pDestImg->Width = TempImg.Width;
	pDestImg->Height = TempImg.Height;
	if (pDestImg->pImg)
	{
		pDestImg->pImg = NULL;
	}
	pDestImg->pImg = TempImg.pImg;

	return res;
}

BYTE GetMedianNum(BYTE *aValue, int iLength)
{
	int i, j;
	BYTE tmp;

	for (j=1; j<iLength; j++)
		for (i=0; i<iLength-j; i++)
		{
			if ((*(aValue+i)) > (*(aValue+i+1)))
			{
				tmp = *(aValue+i);
				*(aValue+i) = *(aValue+i+1);
				*(aValue+i+1) = tmp;
			}
		}

	if ((iLength & 1) > 0)
	{
		tmp = *(aValue+(iLength+1)/2);
	}
	else
	{
		tmp = (*(aValue+iLength/2) + *(aValue+iLength/2+1))/2;
	}

	return tmp;
}

int GetLPPos(RECT *lpRect, PGrayImg pSrcImg)
{
	int res = 0;
	static int TemplateArr[9] = {1,0,-1,   
                                 2,0,-2,
								 1,0,-1};
	static int TemplateArr1[9] = {1,1,1,   
		                          1,0,1,
								  1,1,1};

	TGrayImg EdgeImg;          
	TGrayImg TwoImg;          
	TGrayImg HLPImg, HLPImg1, HLPImg2; 

	int StartYPos=0;           
	int UpYPos=0, DownYPos=0;  
	int LeftXPos=0, RightXPos=0; 
	int Threshold;            

	RECT Rect;

	int *pHProject = NULL;      
	int *pVProject = NULL;    

	BOOL flag;

	res = Template(&EdgeImg, pSrcImg, TemplateArr, 3 ,1);
	if (res == 0)
		return 0;

	StartYPos = EdgeImg.Height - 1;
	Threshold = g_Threshold;

	pHProject = (int*)malloc(pSrcImg->Height*sizeof(int));
	if (NULL == pHProject)
		return 0;

	flag = TRUE;
	while(flag)
	{
		res = TwoPixelCarImg(&TwoImg, &EdgeImg, Threshold);
		if (0 == res)
			return 0;

		res = ProjectImg(pHProject, &TwoImg, H_FILTER);
		if (0 == res)
			return 0;

		res = ProjectFilter(pHProject, TwoImg.Height, H_FILTER);
		if (0 == res)
			return 0;

		res = GetLPYPos(pHProject, TwoImg.Height, &StartYPos, &UpYPos, &DownYPos);
		if (0 == res)
		{
			Threshold -= 10;
			if (Threshold < 50)
			{
				return 0;
			}
		}
		else
		{
			flag = FALSE;
		}

	}
	
	LeftXPos = 0;
	RightXPos = pSrcImg->Width - 1;
	Rect.left = LeftXPos;
	Rect.top = UpYPos;
	Rect.right = RightXPos;
	Rect.bottom = DownYPos;

	res = GetSubImg(&HLPImg1, &EdgeImg, Rect);
	if (0 == res)
		return 0;

////////////////////////////////////////////////////////////////////////////////////////////
	res = Template(&HLPImg2, &HLPImg1, TemplateArr1, 3, 1.0/8.0);
	if (0 == res)
		return 0;

	res = TwoPixelCarImg(&HLPImg, &HLPImg2, g_Threshold_HLP);
	if (0 == res)
		return 0;

	GrayImg_Free(&HLPImg1);
	GrayImg_Free(&HLPImg2);

	pVProject = (int*)malloc(pSrcImg->Width*sizeof(int));
	if (NULL == pVProject)
		return 0;

	res = ProjectImg(pVProject, &HLPImg, V_FILTER);
	if (0 == res)
		return 0;

	res = ProjectFilter(pVProject, pSrcImg->Width, V_FILTER, g_LPAccurateHeight);
	if (0 == res)
		return 0;

	flag = TRUE;
	while(flag)
	{
		res = GetLPXPos(pVProject, pSrcImg->Width, &LeftXPos, &RightXPos);
		if (0 == res)
		{
			res = GetLPYPos(pHProject, pSrcImg->Height, &StartYPos, &UpYPos, &DownYPos);
			if (0 == res)
			{
				StartYPos = pSrcImg->Height - 1;
				res = GetLPYPos(pHProject, pSrcImg->Height, &StartYPos, &UpYPos, &DownYPos);
				if (0 == res)
					return 0;
				else 
				{
					res = GetLPXPos(pVProject, pSrcImg->Width, &LeftXPos, &RightXPos);
					if (0 == res)
						return 0;
					else
					{
						RightXPos += (int)(g_LPWidth * 0.8 + 0.5);
						flag = FALSE;
					}
				}
			}
		}
		else
		{
			if (RightXPos - LeftXPos < 0.6 * g_LPWidth)
			{
				res = GetLPYPos(pHProject, pSrcImg->Height, &StartYPos, &UpYPos, &DownYPos);
				if (0 == res)
				{
					StartYPos = pSrcImg->Height - 1;
					res = GetLPYPos(pHProject, pSrcImg->Height, &StartYPos, &UpYPos, &DownYPos);
					if (0 == res)
						return 0;
					else 
					{
						res = GetLPXPos(pVProject, pSrcImg->Width, &LeftXPos, &RightXPos);
						if (0 == res)
							return 0;
						else
						{
						   RightXPos += (int)(g_LPWidth * 0.8 + 0.5);
						   flag = FALSE;
						}
					}
				}
			}
			else
				flag = FALSE;
		}
	}

	if (pHProject!=NULL)
	{
		free(pHProject);
		pHProject = NULL;
	}

	if (pVProject!=NULL)
	{
		free(pVProject);
		pVProject = NULL;
	}

	lpRect->left = LeftXPos;
	lpRect->right = RightXPos;
	lpRect->top = UpYPos;
	lpRect->bottom = DownYPos;
	
	GrayImg_Free(&HLPImg);
	GrayImg_Free(&TwoImg);
	GrayImg_Free(&EdgeImg);

	return 1;
}

int GetLPYPos(int *pProject, int PrjLen, int *pStartYPos, int *pUpYPos, int *pDownYPos)
{
	int y, Temp;
	BOOL Flag;

	Flag = TRUE;
	*pDownYPos = 0;
	*pUpYPos = 0;
	*(pProject+PrjLen-1) = 0;

	for (y=*pStartYPos; y>=0; y--)
	{
		if ((*(pProject+y)!=0) && Flag)
		{
			*pDownYPos = y;
			Flag = FALSE;
		}
		if ((*(pProject+y) == 0) && (!Flag))
		{
		   *pUpYPos = y;
		   break;
		}
	}

	*pStartYPos = *pUpYPos;

	if (*pDownYPos <= *pUpYPos)
	{
		*pStartYPos = PrjLen-1;
		return 0;
	}

	Temp = *pDownYPos - *pUpYPos;
	if (Temp < g_LPHeight)
	{
	  *pDownYPos = *pDownYPos + (int)((g_LPHeight - Temp) * 0.6 + 0.5);
	  if (*pDownYPos > PrjLen - 1)
		   *pDownYPos = PrjLen - 1;

	  *pUpYPos = *pUpYPos - (int)((g_LPHeight - Temp) * 0.4 + 0.5);

	  if (*pUpYPos < 0)
		   *pUpYPos = 0;
	}

	if (Temp > g_LPHeight * 1.5)
	{
		*pDownYPos = *pDownYPos + (int)(g_LPHeight * 0.125 + 0.5);

		if (*pDownYPos > PrjLen - 1)
		   *pDownYPos = PrjLen - 1;

		*pUpYPos = *pDownYPos - g_LPHeight;

		*pUpYPos = *pUpYPos - (int)(g_LPHeight * 0.15 + 0.5);

		if (*pUpYPos < 0)
			*pUpYPos = 0;
	}

	return 1;
}

int GetLPXPos(int *pProject, int PrjLen, int *pLeftXPos, int *pRightXPos)
{
	int x, Temp;
	int TempLeft, TempRight;
	BOOL flag;

	flag = TRUE;
	Temp = 0;

	*pLeftXPos = 0; 
	*pRightXPos = 0;

	*(pProject+PrjLen-1) = 0;

	for (x=0; x<PrjLen; x++)
	{
		if (flag && (*(pProject+x) != 0))
		{
			TempLeft = x;
			flag = FALSE;
		}

		if ((!flag) && (*(pProject+x) == 0))
		{
			TempRight = x;
			flag = TRUE;
			if (Temp < TempRight - TempLeft)
			{
				*pLeftXPos = TempLeft;
				*pRightXPos = TempRight;
				Temp = TempRight - TempLeft;
			}
		}
	}

	if (*pRightXPos <= *pLeftXPos)
	{
		return 0;
	}
	
	return 1;
}

int Template(PGrayImg pDestImg, PGrayImg pSrcImg, int TemplateArr[], int TemplateN, double Coef)
{
	int temp, y, x, i, j;
	int res = 0;
	TGrayImg TempImg;

	res = GrayImg_Malloc(&TempImg, pSrcImg->Width, pSrcImg->Height);
	if (res == 0)
		return 0;

	for (x=TemplateN/2; x<pSrcImg->Height-TemplateN/2; x++)
		for (y=TemplateN/2; y<pSrcImg->Width-TemplateN/2; y++)
		{
			temp = 0;
			for (i=-TemplateN/2; i<=TemplateN/2; i++)
				for (j=-TemplateN/2; j<=TemplateN/2; j++)
					temp = temp + *(pSrcImg->pImg+(x+i)*pSrcImg->Width+(y+j)) *
		                 TemplateArr[(i+TemplateN/2)*TemplateN+j+TemplateN/2];

			temp = (int)(abs(temp) * Coef + 0.5);

			if (temp > 255)
				temp = 255;

			*(TempImg.pImg+x*TempImg.Width+y) = temp;
		}
	
	for (x=0; x<pSrcImg->Height; x++)
		for (y=0; y<TemplateN/2; y++)
			*(TempImg.pImg+x*TempImg.Width+y) = 0;

	for (x=0; x<pSrcImg->Height; x++)
		for (y=pSrcImg->Width-TemplateN/2; y<pSrcImg->Width; y++)
			*(TempImg.pImg+x*TempImg.Width+y) = 0;

	for (x=0; x<TemplateN/2; x++)
		for (y=0; y<pSrcImg->Width; y++)
			*(TempImg.pImg+x*TempImg.Width+y) = 0;

	for (x=pSrcImg->Height-TemplateN/2; x<pSrcImg->Height; x++)
		for (y=0; y<pSrcImg->Width; y++)
			*(TempImg.pImg+x*TempImg.Width+y) = 0;

	pDestImg->Width = TempImg.Width;
	pDestImg->Height = TempImg.Height;
	pDestImg->pImg = TempImg.pImg;

	return 1;
}

int ProjectImg(int *pProject, PGrayImg pSrcImg,  TPrjType PrjType)
{
	int i, j;

	switch (PrjType)
	{
	case H_FILTER:

		for (i=0; i<pSrcImg->Height; i++)
			*(pProject+i) = 0;

		for (i=0; i<pSrcImg->Height; i++)
			for (j=0; j<pSrcImg->Width; j++)
				*(pProject+i) += *(pSrcImg->pImg+i*pSrcImg->Width+j);

		*(pProject+pSrcImg->Height-1) = 0;

		break;

	case V_FILTER:

		for (i=0; i<pSrcImg->Width; i++)
			*(pProject+i) = 0;

		for (i=0; i<pSrcImg->Height; i++)
			for (j=0; j<pSrcImg->Width; j++)
				*(pProject+j) += *(pSrcImg->pImg+i*pSrcImg->Width+j);

⌨️ 快捷键说明

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