📄 lprprocess.cpp
字号:
/*
* 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 + -