📄 recoprocess.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日
* 完成日期:
*/
#include "stdafx.h"
#include <malloc.h>
#include <math.h>
#include <stdio.h>
#include "../include/types.h"
#include "RecoHelper.h"
#include "RecoProcess.h"
int GetStdImg(PGrayImg pDestImg, PGrayImg pSrcImg)
{
int i, j, res=0;
RECT Rect;
TGrayImg TempImg;
BOOL bFlag = FALSE;
//Rect.top = 0;
//Rect.bottom = pSrcImg->Height-1;
//Rect.left = 0;
//Rect.right = pSrcImg->Width-1;
bFlag = FALSE;
for (i=0; i<pSrcImg->Height; i++)
{
for (j=0; j<pSrcImg->Width; j++)
if (*(pSrcImg->pImg+i*pSrcImg->Width+j) == 255)
{
Rect.top = i;
bFlag = TRUE;
break;
}
if (bFlag)
break;
}
bFlag = FALSE;
for (i=pSrcImg->Height-1; i>=0; i--)
{
for (j=0; j<pSrcImg->Width; j++)
if (*(pSrcImg->pImg+i*pSrcImg->Width+j) == 255)
{
Rect.bottom = i;
bFlag = TRUE;
break;
}
if (bFlag)
break;
}
bFlag = FALSE;
for (j=0; j<pSrcImg->Width; j++)
{
for (i=0; i<pSrcImg->Height; i++)
if (*(pSrcImg->pImg+i*pSrcImg->Width+j) == 255)
{
Rect.left = j;
bFlag = TRUE;
break;
}
if (bFlag)
break;
}
bFlag = FALSE;
for (j=pSrcImg->Width-1; j>=0; j--)
{
for (i=0; i<pSrcImg->Height; i++)
if (*(pSrcImg->pImg+i*pSrcImg->Width+j) == 255)
{
Rect.right = j;
bFlag = TRUE;
break;
}
if (bFlag)
break;
}
res = GrayImg_Malloc(&TempImg, Rect.right-Rect.left+1, Rect.bottom-Rect.top+1);
if (0 == res)
return 0;
for (i=0; i<TempImg.Height; i++)
for (j=0; j<TempImg.Width; j++)
{
*(TempImg.pImg+i*TempImg.Width+j) =
*(pSrcImg->pImg+(i+Rect.top)*pSrcImg->Width+(j+Rect.left));
}
pDestImg->Width = TempImg.Width;
pDestImg->Height = TempImg.Height;
pDestImg->pImg = TempImg.pImg;
return 1;
}
int Zoom(PGrayImg pDestImg, PGrayImg pSrcImg, double HRatio, double VRatio)
{
double numH, numV;
int Wold, Hold, Wnew, Hnew;
int x1, y1, x0, y0;
int res = 0;
TGrayImg TempImg;
if (HRatio == 0.0) HRatio = 1;
if (VRatio == 0.0) VRatio = 1;
numH = 1.0 / HRatio;
numV = 1.0 / VRatio;
Wold = pSrcImg->Width;
Hold = pSrcImg->Height;
Wnew = (int)(Wold * HRatio * 1.0 + 0.5);
Hnew = (int)(Hold * VRatio * 1.0 + 0.5);
res = GrayImg_Malloc(&TempImg, Wnew, Hnew);
if (0 == res)
return 0;
if ((HRatio < 1.0) || (VRatio < 1.0))
{
for (y0=0; y0<pSrcImg->Height; y0++)
for (x0=0; x0<pSrcImg->Width; x0++)
{
if ((*pSrcImg->pImg+y0*pSrcImg->Width+x0) == 255)
{
x1 = (int)(x0 * HRatio * 1.0 + 0.5);
y1 = (int)(y0 * VRatio * 1.0 + 0.5);
if((x1 >= 0) && (x1 < Wnew) && (y1 >= 0) && (y1 < Hnew))
*(TempImg.pImg+y1*TempImg.Width+x1) = *(pSrcImg->pImg+y0*pSrcImg->Width+x0);
}
}
}
else
{
for (y1=0; y1<TempImg.Height; y1++)
for (x1=0; x1<TempImg.Width; x1++)
{
x0 = (int)(x1 * numH);
y0 = (int)(y1 * numV);
if((x0 >= 0) && (x0 < Wold) && (y0 >= 0) && (y0 < Hold))
*(TempImg.pImg+y1*TempImg.Width+x1) = *(pSrcImg->pImg+y0*pSrcImg->Width+x0);
}
}
pDestImg->Width = TempImg.Width;
pDestImg->Height = TempImg.Height;
pDestImg->pImg = TempImg.pImg;
return 1;
}
int ImgMatch(int *pMatchNum, PGrayImg pSrcImg, PGrayImg pModelImg)
{
int x, y;
int ImgCount;
int Width, Height;
ImgCount = 0;
if (pSrcImg->Width > pModelImg->Width)
Width = pModelImg->Width;
else
Width = pSrcImg->Width;
if (pSrcImg->Height > pModelImg->Height)
Height = pModelImg->Height;
else
Height = pSrcImg->Height;
for (y=0; y<Height; y++)
for (x=0; x<Width; x++)
{
ImgCount += abs(*(pSrcImg->pImg+y*pSrcImg->Width+x) - *(pModelImg->pImg+y*pModelImg->Width+x)) / 255;
}
*pMatchNum = ImgCount;
return 1;
}
int RecoAgain(int *pCarSignID, PGrayImg pLPCharImg, int MatchNum[], TLPNumType LPNumType)
{
int CarSignID;
int i, j, nCount, nAllCount;
int FirstY=0;
BOOL bFlag;
CarSignID = *pCarSignID;
switch (CarSignID)
{
case 'G'-'A'+10:
if (MatchNum['G'-'A'+10] == 0) break;
if ((1.0*MatchNum[0]-MatchNum['G'-'A'+10])/MatchNum['G'-'A'+10] > 0.20 &&
(1.0*MatchNum[8]-MatchNum['G'-'A'+10])/MatchNum['G'-'A'+10] > 0.20 &&
(1.0*MatchNum['Q'-'A'+10]-MatchNum['G'-'A'+10])/MatchNum['G'-'A'+10] > 0.20 &&
(1.0*MatchNum['D'-'A'+10]-MatchNum['G'-'A'+10])/MatchNum['G'-'A'+10] > 0.20)
break;
bFlag = FALSE;
nCount = 0;
for (j=0; j<pLPCharImg->Width; j++)
{
i = (int)(1.0/3.0*pLPCharImg->Height);
if (*(pLPCharImg->pImg+i*pLPCharImg->Width+j)==255 && !bFlag)
{
nCount++;
bFlag = TRUE;
}
if (*(pLPCharImg->pImg+i*pLPCharImg->Width+j) == 0 && bFlag)
{
bFlag = FALSE;
}
}
if (nCount > 1)
{
switch (LPNumType)
{
case LPNUM_EN:
*pCarSignID = 'O'-'A'+10;
RecoAgain(pCarSignID, pLPCharImg, MatchNum, LPNumType);
break;
case LPNUM_ENNUM:
*pCarSignID = 0;
RecoAgain(pCarSignID, pLPCharImg, MatchNum, LPNumType);
break;
}
}
break;
case 'Z'-'A'+10:
if (MatchNum['Z'-'A'+10] == 0) break;
if ((1.0*MatchNum[2]-MatchNum['Z'-'A'+10])/MatchNum['Z'-'A'+10] > 0.40)
break;
nCount = 0;
nAllCount = 0;
for (i=0; i<(int)(0.1*pLPCharImg->Height+0.5); i++)
for (j=(int)(0.9*pLPCharImg->Width); j<pLPCharImg->Width; j++)
{
if (*(pLPCharImg->pImg+i*pLPCharImg->Width+j) == 255)
nCount++;
nAllCount++;
}
if (0 == nAllCount) break;
if (nCount*1.0/nAllCount < 0.5)
{
switch (LPNumType)
{
case LPNUM_EN:
break;
case LPNUM_ENNUM:
*pCarSignID = 2;
break;
}
}
break;
case 8:
if (MatchNum[8] == 0) break;
if ((1.0*MatchNum[0]-MatchNum[8])/MatchNum[8] > 0.20 &&
(1.0*MatchNum['D'-'A'+10]-MatchNum[8])/MatchNum[8] > 0.20 &&
(1.0*MatchNum['G'-'A'+10]-MatchNum[8])/MatchNum[8] > 0.20 &&
(1.0*MatchNum['Q'-'A'+10]-MatchNum[8])/MatchNum[8] > 0.20 &&
(1.0*MatchNum['B'-'A'+10]-MatchNum[8])/MatchNum[8] > 0.20)
break;
bFlag = FALSE;
nCount = 0;
i = (int)(1.0/3.0*pLPCharImg->Height);
for (j=0; j<pLPCharImg->Width; j++)
{
if (*(pLPCharImg->pImg+i*pLPCharImg->Width+j)==255 && !bFlag)
{
nCount++;
bFlag = TRUE;
}
if (*(pLPCharImg->pImg+i*pLPCharImg->Width+j) == 0 && bFlag)
{
bFlag = FALSE;
}
}
if (nCount <=1)
{
switch (LPNumType)
{
case LPNUM_ENNUM:
*pCarSignID = 'G'-'A'+10;
break;
}
break;
}
bFlag = FALSE;
nCount = 0;
FirstY = 0;
for (i=0; i<pLPCharImg->Height; i++)
{
j = (int)(1.0/2.0*pLPCharImg->Width);
if (*(pLPCharImg->pImg+i*pLPCharImg->Width+j)==255 && !bFlag)
{
if (nCount == 0)
FirstY = i;
nCount++;
bFlag = TRUE;
}
if (*(pLPCharImg->pImg+i*pLPCharImg->Width+j) == 0 && bFlag)
{
bFlag = FALSE;
}
}
if (nCount < 3 && FirstY < (int)(0.3*pLPCharImg->Height))
{
switch (LPNumType)
{
case LPNUM_NUM:
*pCarSignID = 0;
break;
case LPNUM_ENNUM:
*pCarSignID = 0;
RecoAgain(pCarSignID, pLPCharImg, MatchNum, LPNumType);
break;
}
}
else
{
nCount = 0;
nAllCount = 0;
for (i=0; i<(int)(0.1*pLPCharImg->Height+0.5); i++)
for (j=0; j<(int)(0.2*pLPCharImg->Width+0.5); j++)
{
if (*(pLPCharImg->pImg+i*pLPCharImg->Width+j) == 255)
nCount++;
nAllCount++;
}
if (0 == nAllCount) break;
if (nCount*1.0/nAllCount > 0.8)
{
switch (LPNumType)
{
case LPNUM_ENNUM:
*pCarSignID = 'B'-'A'+10;
break;
}
}
}
break;
case 0:
if (MatchNum[0] == 0) break;
if ((1.0*MatchNum['D'-'A'+10]-MatchNum[0])/MatchNum[0] > 0.20 &&
(1.0*MatchNum['Q'-'A'+10]-MatchNum[0])/MatchNum[0] > 0.20)
break;
nCount = 0;
nAllCount = 0;
for (i=0; i<(int)(0.15*pLPCharImg->Height+0.5); i++)
for (j=0; j<(int)(0.3*pLPCharImg->Width+0.5); j++)
{
if (*(pLPCharImg->pImg+i*pLPCharImg->Width+j) == 255)
nCount++;
nAllCount++;
}
if (0 == nAllCount) break;
if (nCount*1.0/nAllCount > 0.7)
{
switch (LPNumType)
{
case LPNUM_ENNUM:
*pCarSignID = 'D'-'A'+10;
break;
}
}
else
{
nCount = 0;
for (i=(int)(0.75*pLPCharImg->Height); i<pLPCharImg->Height; i++)
for (j=(int)(0.5*pLPCharImg->Width); j<pLPCharImg->Width; j++)
{
if (*(pLPCharImg->pImg+i*pLPCharImg->Width+j) == 255)
nCount++;
}
nAllCount = 0;
for (i=(int)(0.75*pLPCharImg->Height); i<pLPCharImg->Height; i++)
for (j=0; j<(int)(0.5*pLPCharImg->Width+0.5); j++)
{
if (*(pLPCharImg->pImg+i*pLPCharImg->Width+j) == 255)
nAllCount++;
}
if (0 == nAllCount) break;
if (nCount*1.0/nAllCount > 1.3)
{
switch (LPNumType)
{
case LPNUM_ENNUM:
*pCarSignID = 'Q'-'A'+10;
break;
}
}
}
break;
case 'O'-'A'+10:
if (MatchNum['O'-'A'+10] == 0) break;
if ((1.0*MatchNum['D'-'A'+10]-MatchNum['O'-'A'+10])/MatchNum['O'-'A'+10] > 0.20 &&
(1.0*MatchNum['Q'-'A'+10]-MatchNum['O'-'A'+10])/MatchNum['O'-'A'+10] > 0.20)
break;
nCount = 0;
nAllCount = 0;
for (i=0; i<(int)(0.1*pLPCharImg->Height+0.5); i++)
for (j=0; j<(int)(0.2*pLPCharImg->Width+0.5); j++)
{
if (*(pLPCharImg->pImg+i*pLPCharImg->Width+j) == 255)
nCount++;
nAllCount++;
}
if (0 == nAllCount) break;
if (nCount*1.0/nAllCount > 0.5)
{
switch (LPNumType)
{
case LPNUM_EN:
*pCarSignID = 'D'-'A'+10;
break;
}
}
else
{
nCount = 0;
for (i=(int)(0.75*pLPCharImg->Height); i<pLPCharImg->Height; i++)
for (j=(int)(0.5*pLPCharImg->Width); j<pLPCharImg->Width; j++)
{
nCount++;
}
nAllCount = 0;
for (i=(int)(0.75*pLPCharImg->Height); i<pLPCharImg->Height; i++)
for (j=0; j<(int)(0.5*pLPCharImg->Width+0.5); j++)
{
nAllCount++;
}
if (0 == nAllCount) break;
if (nCount*1.0/nAllCount > 1.2)
{
switch (LPNumType)
{
case LPNUM_EN:
*pCarSignID = 'Q'-'A'+10;
break;
}
}
}
break;
case 4:
if (MatchNum[4] == 0) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -