www.gusucode.com > 基于C++的TRY2LPR-1.0开源车牌识别核心-源码程序 > 基于C++的TRY2LPR-1.0开源车牌识别核心-源码程序\code\LPR\LPRProcess.cpp
//Download by http://www.NewXing.com /* * 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); *(pProject+pSrcImg->Width-1) = 0; break; default: return 0; } return 1; } int ProjectFilter(int *pProject, int PrjLen, TPrjType PrjType, int LPAccurateHeight) { int i, j, p; int Temp, Temp1; BOOL Flag1, Flag2; int avg, CharID; int TempLeft[100], TempRight[100]; int TempWidth[100], MergeID[100]; *(pProject + PrjLen - 1) = 0; switch (PrjType) { case H_FILTER: for (i=0; i<PrjLen; i++) { if (*(pProject+i) < 38 * 255) *(pProject+i) = 0; } Flag1 = TRUE; for (i=0; i<PrjLen; i++) { avg = 0; if ((*(pProject+i) != 0) && Flag1) { Temp = i; Flag1 = FALSE; } if ((*(pProject+i) == 0) && (!Flag1)) { for (j=Temp; j<=i; j++) avg = avg + *(pProject+j) / 255; avg = avg / (i - Temp); if ((i-Temp<(int)(g_LPHeight*0.35+0.5)) || (avg<(int)(g_LPWidth*0.30+0.5))) { for (j=Temp; j<i; j++) *(pProject+j) = 0; } Flag1 = TRUE; } } break; case V_FILTER: for (j=0; j<PrjLen; j++) { if (*(pProject+j) < (int)(0.2*g_LPHeight*255+0.5)) *(pProject+j) = 0; } Flag1 = TRUE; for (i=0; i<PrjLen; i++) { avg = 0; if ((*(pProject+i)!=0) && Flag1) { Temp = i; Flag1 = FALSE; } if ((*(pProject+i) == 0) && (!Flag1)) { for (j=Temp; j<=i; j++) avg = avg + *(pProject+j)/255; avg = avg / (i - Temp); if ((i-Temp<(int)(g_LPWidth*0.015+0.5)) || (avg<(int)(g_LPHeight*0.15+0.5))) { for (j=Temp; j<i; j++) *(pProject+j) = 0; } Flag1 = TRUE; } } Flag2 = TRUE; Flag1 = TRUE; for (i=0; i<PrjLen; i++) { if ((*(pProject+i)!=0) && Flag1) { Flag1 = FALSE; } if ((*(pProject+i)==0) && (!Flag1)) { Temp1 = i; Flag1 = TRUE; Flag2 = FALSE; } if ((*(pProject+i)!=0) && (!Flag2)) { if ((i-Temp1)<(int)(0.11*g_LPWidth+0.5)) { for (j=Temp1; j<i; j++) *(pProject+j) = 17 * 255; } Flag2 = TRUE; } } Flag1 = TRUE; Temp = 0; for (i=0; i<PrjLen; i++) { if ((*(pProject+i) != 0) && Flag1) { Temp = i; Flag1 = FALSE; } if ((*(pProject+i)==0) && (!Flag1)) { if (i-Temp > (int)(g_LPWidth*1.5+0.5)) { for (j=Temp; j<i; j++) *(pProject+j) = 0; } Flag1 = TRUE; } } break; case IH_FILTER : for (i=0; i<PrjLen; i++) { if (*(pProject+i) < 16 * 255) { *(pProject+i) = 0; } } break; case IV_FILTER : for (i=0; i<PrjLen; i++) { if (*(pProject+i) < (int)(0.1*LPAccurateHeight+0.5)*255) *(pProject+i) = 0; } Flag1 = TRUE; for (i=0; i<PrjLen; i++) { if ((*(pProject+i) != 0) && Flag1) { Temp = i; Flag1 = FALSE; } if ((*(pProject+i) == 0) && (!Flag1)) { if (i - Temp < (int)(0.2 * LPAccurateHeight + 0.5)) { for (j=Temp; j<i; j++) if (*(pProject+j) < (int)(0.3*LPAccurateHeight + 0.5)*255) *(pProject+j) = 0; } Flag1 = TRUE; } } if (PrjLen > (int)(4.6 * LPAccurateHeight + 0.5)) { Flag2 = TRUE; Flag1 = TRUE; for (i=0; i<=(int)((PrjLen-1)/3.0); i++) { if ((*(pProject+i) != 0) && Flag1) { Flag1 = FALSE; } if ((*(pProject+i) == 0) && (!Flag1)) { Temp1 = i; Flag1 = TRUE; Flag2 = FALSE; } if ((*(pProject+i) != 0) && (!Flag2)) { if (i-Temp1 > (int)(0.6*LPAccurateHeight+0.5)) { for (j=i-1; j>=0; j--) *(pProject+j) = 0; } Flag2 = TRUE; } } Flag1 = TRUE; CharID = 0; for (i=0; i<=(int)((PrjLen-1)/2.0); i++) { if ((*(pProject+i) != 0) && Flag1) { TempLeft[CharID] = i; Flag1 = FALSE; } if ((*(pProject+i) == 0) && (!Flag1)) { TempRight[CharID] = i; TempWidth[CharID] = TempRight[CharID] - TempLeft[CharID]; CharID++; if (CharID > 100) { return 0; } Flag1 = TRUE; } } j = 0; for (i=0; i<CharID; i++) { if (TempWidth[i] < (int)(0.35*LPAccurateHeight+0.5)) { MergeID[j] = i; j++; } if ((i==CharID-1) || (TempWidth[i]>=(int)(0.35*LPAccurateHeight+0.5))) { if (j > 1) { for (p=TempLeft[MergeID[0]]; p<=TempRight[MergeID[j-1]]; p++) { *(pProject+p) = (int)(0.5 * LPAccurateHeight + 0.5) * 255; } } j = 0; } } } Flag1 = TRUE; for (i=0; i<PrjLen; i++) { if ((*(pProject+i) != 0) && Flag1) { Temp = i; Flag1 = FALSE; } if ((*(pProject+i) == 0) && (!Flag1)) { if (i-Temp < (int)(0.3*LPAccurateHeight+0.5)) { for (j=Temp; j<i; j++) *(pProject+j) = 0; } Flag1 = TRUE; } } break; default: return 0; } return 1; } int TwoPixelCarImg(PGrayImg pDestImg, PGrayImg pSrcImg, int Threshold) { int i, j; int res = 0; TGrayImg TempImg; res = GrayImg_Malloc(&TempImg, pSrcImg->Width, pSrcImg->Height); if (res == 0) return 0; for (i=0; i<pSrcImg->Height; i++) for (j=0; j<pSrcImg->Width; j++) { if (*(pSrcImg->pImg+i*pSrcImg->Width+j) > Threshold) *(TempImg.pImg+TempImg.Width*i+j) = 255; else *(TempImg.pImg+TempImg.Width*i+j) = 0; } pDestImg->Width = TempImg.Width; pDestImg->Height = TempImg.Height; pDestImg->pImg = TempImg.pImg; return 1; } int GetSubImg(PGrayImg pDestImg, PGrayImg pSrcImg, RECT Rect) { int i, j; int res = 0; TGrayImg TempImg; int Left=0, Right=0, Top=0, Bottom=0; res = GrayImg_Malloc(&TempImg, Rect.right-Rect.left+1, Rect.bottom-Rect.top+1); if (0 == res) return 0; for (i=Rect.top; i<=Rect.bottom; i++) for (j=Rect.left; j<=Rect.right; j++) { if ((i>=0 && i<pSrcImg->Height) && (j>=0 && j<pSrcImg->Width)) *(TempImg.pImg+(i-Rect.top)*TempImg.Width+(j-Rect.left)) = *(pSrcImg->pImg+i*pSrcImg->Width+j); else *(TempImg.pImg+(i-Rect.top)*TempImg.Width+(j-Rect.left)) = 0; } pDestImg->Width = TempImg.Width; pDestImg->Height = TempImg.Height; pDestImg->pImg = TempImg.pImg; return 1; } int GetSubColorImg(PColorImg pDestImg, PColorImg pSrcImg, RECT Rect) { int i, j; int res = 0; TColorImg TempImg; res = ColorImg_Malloc(&TempImg, Rect.right-Rect.left+1, Rect.bottom-Rect.top+1); if (0 == res) return 0; for (i=Rect.top; i<=Rect.bottom; i++) for (j=Rect.left; j<=Rect.right; j++) { if ((i>=0 && i<pSrcImg->Height) && (j>=0 && j<pSrcImg->Width)) { *(TempImg.pRImg+(i-Rect.top)*TempImg.Width+(j-Rect.left)) = *(pSrcImg->pRImg+i*pSrcImg->Width+j); *(TempImg.pGImg+(i-Rect.top)*TempImg.Width+(j-Rect.left)) = *(pSrcImg->pGImg+i*pSrcImg->Width+j); *(TempImg.pBImg+(i-Rect.top)*TempImg.Width+(j-Rect.left)) = *(pSrcImg->pBImg+i*pSrcImg->Width+j); *(TempImg.pYImg+(i-Rect.top)*TempImg.Width+(j-Rect.left)) = *(pSrcImg->pYImg+i*pSrcImg->Width+j); } else { *(TempImg.pRImg+(i-Rect.top)*TempImg.Width+(j-Rect.left)) = 0; *(TempImg.pGImg+(i-Rect.top)*TempImg.Width+(j-Rect.left)) = 0; *(TempImg.pBImg+(i-Rect.top)*TempImg.Width+(j-Rect.left)) = 0; *(TempImg.pYImg+(i-Rect.top)*TempImg.Width+(j-Rect.left)) = 0; } } TempImg.BitCount = pSrcImg->BitCount; pDestImg->Width = TempImg.Width; pDestImg->Height = TempImg.Height; pDestImg->pRImg = TempImg.pRImg; pDestImg->pGImg = TempImg.pGImg; pDestImg->pBImg = TempImg.pBImg; pDestImg->pYImg = TempImg.pYImg; pDestImg->BitCount = TempImg.BitCount; return 1; } int RecoLPColor(TColorID *pLPColorID, PColorImg pSrcImg) { int i, j; int ACount[4]; int Temp; BYTE R, G, B; ACount[LP_BLACK] = 0; ACount[LP_BLUE] = 0; ACount[LP_YELLOW] = 0; ACount[LP_WHITE] = 0; for (i=(int)(0.15*pSrcImg->Height+0.5); i<(int)(pSrcImg->Height-0.15*pSrcImg->Height+0.5); i++) for (j=(int)(0.15*pSrcImg->Width+0.5); j<(int)(pSrcImg->Width-0.15*pSrcImg->Width+0.5); j++) { R = *(pSrcImg->pRImg+i*pSrcImg->Width+j); G = *(pSrcImg->pGImg+i*pSrcImg->Width+j); B = *(pSrcImg->pBImg+i*pSrcImg->Width+j); if ((B-G>g_BYDiff) && (B-R>g_BYDiff) && (B>g_BYLP)) ACount[LP_BLUE]++; if ((R-B>g_BYDiff) && (G-B>g_BYDiff) && (R>g_BYLP) && (G>g_BYLP)) ACount[LP_YELLOW]++; if ((B<g_BlackLP)&&(G<g_BlackLP)&&(R<g_BlackLP)&&(abs(G-B)<g_BWDiff)&&(abs(G-R)<g_BWDiff)&&(abs(B-R)<g_BWDiff)) ACount[LP_BLACK]++; if ((R>g_WhiteLP)&&(G>g_WhiteLP)&&(B>g_WhiteLP)&&(abs(G-B)<g_BWDiff)&&(abs(G-R)<g_BWDiff)&&(abs(B-R)<g_BWDiff)) ACount[LP_WHITE]++; } Temp = ACount[LP_BLUE]; *pLPColorID = LP_BLUE; for (i=0; i<4; i++) if (Temp < ACount[i]) { Temp = ACount[i]; *pLPColorID = (TColorID)i; } return 1; } int TwoPixelLPImg(PGrayImg pDestImg, PGrayImg pSrcImg, double MaxBlackRatio, double MinBlackRatio, int *pThreshold) { int i, j; int res = 0; int TempArray[9] = {1,1,1, 1,0,1, 1,1,1}; int TempArray1[9] = {-1,0,1, -1,0,1, -1,0,1}; int *pProject=NULL; int WhitePixelCount, BlackPixelCount; int Bottom, Top; BOOL StopFlag1, StopFlag2; TGrayImg TempImg, EdgeImg, TempImg1; Top = 0; Bottom = pSrcImg->Height-1; res = Template(&EdgeImg, pSrcImg, TempArray1, 3, 1); if (0 == res) return 0; res = Template(&TempImg1, &EdgeImg, TempArray, 3, 1.0/8.0); if (0 == res) return 0; res = TwoPixelCarImg(&TempImg, &TempImg1, g_Threshold_HLP); if (0 == res) return 0; pProject = (int*)malloc(pSrcImg->Height*sizeof(int)); if (pProject == NULL) return 0; res = ProjectImg(pProject, &TempImg, H_FILTER); if (0 == res) return 0; for (i=0; i<pSrcImg->Height; i++) if (*(pProject+i) < int(0.25*pSrcImg->Height)) *(pProject+i) = 0; for (i=pSrcImg->Height/2; i>=0; i--) { if (*(pProject+i) == 0) { Top = i; break; } } for (i=pSrcImg->Height/2; i<pSrcImg->Height; i++) { if (*(pProject+i) == 0) { Bottom = i; break; } } if (pProject) free(pProject); GrayImg_Free(&EdgeImg); GrayImg_Free(&TempImg1); GrayImg_Free(&TempImg); *pThreshold = 50; res = GrayImg_Malloc(&TempImg, pSrcImg->Width, pSrcImg->Height); if (res == 0) return 0; StopFlag1 = FALSE; StopFlag2 = FALSE; while(TRUE) { BlackPixelCount = 0; WhitePixelCount = 0; for (i=0; i<pSrcImg->Height; i++) for (j=0; j<pSrcImg->Width; j++) { if (*(pSrcImg->pImg+i*pSrcImg->Width+j) > *pThreshold) { if (i>=Top && i<=Bottom) WhitePixelCount++; *(TempImg.pImg+i*TempImg.Width+j) = 255; } else { if (i>=Top && i<=Bottom) BlackPixelCount++; *(TempImg.pImg+i*TempImg.Width+j) = 0; } } if ((BlackPixelCount<=(int)(MaxBlackRatio*(BlackPixelCount+WhitePixelCount)+0.5)) && (BlackPixelCount>=(int)(MinBlackRatio*(BlackPixelCount+WhitePixelCount)+0.5))) break; if (BlackPixelCount>(int)(MaxBlackRatio*(BlackPixelCount+WhitePixelCount)+0.5)) { StopFlag1 = TRUE; *pThreshold -= 5; if (StopFlag2) break; } if (BlackPixelCount < (int)(MinBlackRatio*(BlackPixelCount+WhitePixelCount)+0.5)) { StopFlag2 = TRUE; *pThreshold += 5; if (StopFlag1) break; } } pDestImg->Width = TempImg.Width; pDestImg->Height = TempImg.Height; pDestImg->pImg = TempImg.pImg; return 1; } int Invert(PGrayImg pDestImg, PGrayImg pSrcImg) { int i, j; int res = 0; TGrayImg TempImg; res = GrayImg_Malloc(&TempImg, pSrcImg->Width, pSrcImg->Height); if (0 == res) return 0; for (i=0; i<pSrcImg->Height; i++) for (j=0; j<pSrcImg->Width; j++) { *(TempImg.pImg+i*TempImg.Width+j) = 255 - *(pSrcImg->pImg+i*pSrcImg->Width+j); } pDestImg->Width = TempImg.Width; pDestImg->Height = TempImg.Height; pDestImg->pImg = TempImg.pImg; return 1; } int RectifyLP(PGrayImg pDestImg, PGrayImg pSrcImg, PGrayImg pModelImg) { int i, j; int res = 0; TAngle Angle; double RectifyAngle; int iAngle; TGrayImg TempImg1, TempImg2; TGrayImg RowDiffImg; res = Diff(&RowDiffImg, pModelImg, H_FILTER); if (0 == res) return 0; res = HoughTrans(&Angle, &RowDiffImg, V_FILTER); if (0 == res) return 0; res = GrayImg_Free(&RowDiffImg); if (0 == res) return 0; res = Diff(&RowDiffImg, pModelImg, V_FILTER); if (0 == res) return 0; res = HoughTrans(&Angle, &RowDiffImg, H_FILTER); if (0 == res) return 0; res = GrayImg_Free(&RowDiffImg); if (0 == res) return 0; res = GrayImg_Malloc(&TempImg1, pSrcImg->Width, pSrcImg->Height); if (0 == res) return 0; for (i=0; i<pSrcImg->Height; i++) for (j=0; j<pSrcImg->Width; j++) *(TempImg1.pImg+i*TempImg1.Width+j) = 0; if (fabs(Angle.HAngle+90) != 90.0) RectifyAngle = -(Angle.HAngle + 90.0)/180.0*PI; for (i=0; i<pSrcImg->Width; i++) for (j=0; j<pSrcImg->Height; j++) { if (i*tan(RectifyAngle) < 0.0) iAngle = (int)(i*tan(RectifyAngle)-0.5); else iAngle = (int)(i*tan(RectifyAngle)+0.5); if ((j-iAngle >= 0) && (j-iAngle < pSrcImg->Height)) *(TempImg1.pImg+j*TempImg1.Width+i) = *(pSrcImg->pImg+(j-iAngle)*pSrcImg->Width+i); } res = GrayImg_Malloc(&TempImg2, pSrcImg->Width, pSrcImg->Height); if (0 == res) return 0; for (i=0; i<pSrcImg->Height; i++) for (j=0; j<pSrcImg->Width; j++) *(TempImg2.pImg+i*TempImg2.Width+j) = 0; if (fabs(Angle.VAngle) != 90.0) RectifyAngle = Angle.VAngle/180.0*PI; for (i=0; i<TempImg1.Height; i++) for (j=0; j<TempImg1.Width; j++) { if (i*tan(RectifyAngle) < 0.0) iAngle = (int)(i*tan(RectifyAngle)-0.5); else iAngle = (int)(i*tan(RectifyAngle)+0.5); if ((j-iAngle >= 0) && (j-iAngle < TempImg1.Width)) *(TempImg2.pImg+i*TempImg2.Width+j) = *(TempImg1.pImg+i*TempImg1.Width+j-iAngle); } res = GrayImg_Free(&TempImg1); if (0 == res) return 0; pDestImg->Width = TempImg2.Width; pDestImg->Height = TempImg2.Height; pDestImg->pImg = TempImg2.pImg; return 1; } int Diff(PGrayImg pDestImg, PGrayImg pSrcImg, TPrjType PrjType) { int i, j; int Temp; int res = 0; TGrayImg TempImg; res = GrayImg_Malloc(&TempImg, pSrcImg->Width, pSrcImg->Height); if (res == 0) return 0; switch(PrjType) { case H_FILTER: for (i=0; i<pSrcImg->Height; i++) *(TempImg.pImg+i*TempImg.Width+0) = 0; for (i=0; i<pSrcImg->Height; i++) for (j=1; j<pSrcImg->Width; j++) { Temp = abs(*(pSrcImg->pImg+i*pSrcImg->Width+j)-*(pSrcImg->pImg+i*pSrcImg->Width+j-1)); if (Temp > 80) Temp = 255; else Temp = 0; *(TempImg.pImg+i*TempImg.Width+j) = Temp; } break; case V_FILTER: for (j=0; j<pSrcImg->Width; j++) *(TempImg.pImg+0+j) = 0; for (j=0; j<pSrcImg->Width; j++) for (i=1; i<pSrcImg->Height; i++) { Temp = abs(*(pSrcImg->pImg+i*pSrcImg->Width+j)-*(pSrcImg->pImg+(i-1)*pSrcImg->Width+j)); if (Temp > 80) Temp = 255; else Temp = 0; *(TempImg.pImg+i*TempImg.Width+j) = Temp; } break; default: return 0; } pDestImg->Width = TempImg.Width; pDestImg->Height = TempImg.Height; pDestImg->pImg = TempImg.pImg; return 1; } int HoughTrans(PAngle pAngle, PGrayImg pSrcImg, TPrjType PrjType) { int i, j, p, o, Max, Tempo; int *H; int HWidth, HHeight; double temp; o = -90; p = 0; HHeight = 4 * pSrcImg->Width + 1; HWidth = 181; H = (int*)malloc(HWidth*HHeight*sizeof(int)); if (NULL == H) return 0; for (i=-(HHeight/2); i<=(HHeight/2); i++) for (j=-(HWidth/2); j<=(HWidth/2); j++) *(H+(i+HHeight/2)*HWidth+j+HWidth/2) = 0; switch (PrjType) { case H_FILTER: for (i=0; i<pSrcImg->Height; i++) for (j=0; j<pSrcImg->Width; j++) { if (*(pSrcImg->pImg+i*pSrcImg->Width+j) == 255) { for (o=-10; o<=10; o++) { if (o >= 0) Tempo = o + 80; else Tempo = o - 80; temp = j*cos(Tempo*PI/180.0)+i*sin(Tempo*PI/180.0); if (temp < 0.0) p = (int)(temp-0.5); else p = (int)(temp+0.5); if ((p+HHeight/2 >= 0) && (p + HHeight/2 < HHeight)) (*(H+(p+HHeight/2)*HWidth+Tempo+HWidth/2))++; } } } Max = 0; for (i=-HHeight/2; i<=HHeight/2; i++) for (j=-10; j<=10; j++) { if (j >= 0) Tempo = j + 80; else Tempo = j - 80; if (Max<*(H+(i+HHeight/2)*HWidth+Tempo+HWidth/2)) { Max = *(H+(i+HHeight/2)*HWidth+Tempo+HWidth/2); o = Tempo; p = i; } } pAngle->HAngle = o; break; case V_FILTER: for (i=0; i<pSrcImg->Height; i++) for (j=0; j<pSrcImg->Width; j++) { if (*(pSrcImg->pImg+i*pSrcImg->Width+j) == 255) { for (o=-10; o<=10; o++) { temp = j*cos(o*PI/180.0)+i*sin(o*PI/180.0); if (temp < 0.0) p = (int)(temp-0.5); else p = (int)(temp+0.5); if ((p+HHeight/2 >= 0) && (p+HHeight/2 < HHeight)) (*(H+(p+HHeight/2)*HWidth+o+HWidth/2))++; } } } Max = 0; for (i=-HHeight/2; i<=HHeight/2; i++) for (j=-10; j<=10; j++) { if (Max < *(H+(i+HHeight/2)*HWidth+j+HWidth/2)) { Max = *(H+(i+HHeight/2)*HWidth+j+HWidth/2); o = j; p = i; } } pAngle->VAngle = o; break; default: if (H) free(H); return 0; } if (H) { free(H); H = NULL; } return 1; } int GetLPAccuratePos(RECT *lpRect, PGrayImg pSrcImg) { int res = 0; TGrayImg DiffImg; TGrayImg LPImg; int UpYPos, DownYPos, LeftXPos, RightXPos; int *pHProject, *pVProject; res = Diff(&DiffImg, pSrcImg, H_FILTER); if (0 == res) return 0; pHProject = (int*)malloc(pSrcImg->Height*sizeof(int)); res = ProjectImg(pHProject, &DiffImg, H_FILTER); if (0 == res) return 0; res = ProjectFilter(pHProject, pSrcImg->Height, IH_FILTER); if (0 == res) return 0; res = GetLPAccurateYPos(pHProject, pSrcImg->Height, &UpYPos, &DownYPos); if (0 == res) return 0; lpRect->left = 0; lpRect->right = pSrcImg->Width - 1; lpRect->top = UpYPos; lpRect->bottom = DownYPos; res = GetSubImg(&LPImg, pSrcImg, *lpRect); if (0 == res) return 0; res = GrayImg_Free(&DiffImg); if (0 == res) return 0; pVProject = (int*)malloc(LPImg.Width*sizeof(int)); res = ProjectImg(pVProject, &LPImg, V_FILTER); if (0 == res) return 0; res = ProjectFilter(pVProject, LPImg.Width, IV_FILTER, DownYPos - UpYPos); if (0 == res) return 0; res = GetLPAccurateXPos(pVProject, LPImg.Width, DownYPos - UpYPos, &LeftXPos, &RightXPos); if (0 == res) return 0; if (pHProject != NULL) { free(pHProject); pHProject = NULL; } if (pVProject != NULL) { free(pVProject); pVProject = NULL; } res = GrayImg_Free(&LPImg); if (0 == res) return 0; lpRect->top = UpYPos; lpRect->bottom = DownYPos; lpRect->left = LeftXPos; lpRect->right = RightXPos; return 1; } int GetLPAccurateXPos(int *pProject, int PrjLen, int LPHeight, int *pLeftXPos, int *pRightXPos) { int i, j, k; int TempLeft, TempRight; int TempPos[101], Code[101]; BOOL Flag1, Flag2; *pLeftXPos = 0; *pRightXPos = 0; for (i=0; i<PrjLen; i++) { if (*(pProject+i) != 0) { *pLeftXPos = i; break; } } if ((int)(4.4*LPHeight+0.5)+(*pLeftXPos) > PrjLen-1) *pRightXPos = PrjLen - 1; else *pRightXPos = (int)(4.4 * LPHeight + 0.5) + (*pLeftXPos); if (*(pProject+(*pRightXPos)) != 0) { for (i=(*pRightXPos); i<PrjLen; i++) { if (*(pProject+i) == 0) break; } *pRightXPos = i; } if ((*pRightXPos)-(*pLeftXPos) > (int)(4.0*LPHeight+0.5)) { Flag2 = TRUE; Flag1 = TRUE; j = 0; k = 0; for (i=(*pLeftXPos); i<PrjLen; i++) { if ((*(pProject+i) != 0) && Flag1) Flag1 = FALSE; if ((*(pProject+i) == 0) && (!Flag1)) { TempPos[j] = i; j++; if (j > 100) { return 0; } TempLeft = i; Flag1 = TRUE; Flag2 = FALSE; } if ((*(pProject+i) != 0) && (!Flag2)) { TempRight = i; if (TempRight-TempLeft < (int)(0.25*LPHeight+0.5)) Code[k] = 0; else Code[k] = 1; k++; if (k > 100) return 0; Flag2 = TRUE; } } for (i=0; i<=j-2; i++) { if (Code[i] == 0) { if (Code[i+1] == 1) { if (TempPos[i]-(int)(0.45*LPHeight+0.5) > 0) *pLeftXPos = TempPos[i]-(int)(0.45*LPHeight+0.5); else *pLeftXPos = 0; break; } } } if ((int)(4.4*LPHeight+0.5)+(*pLeftXPos) < PrjLen-1) *pRightXPos = (int)(4.4*LPHeight+0.5)+(*pLeftXPos); else *pRightXPos = PrjLen - 1; if (*(pProject+(*pRightXPos)) != 0) { for (i=(*pRightXPos); i<PrjLen; i++) { if (*(pProject+i) == 0) break; } *pRightXPos = i; } } if ((*pRightXPos) <= (*pLeftXPos)) { return 0; } return 1; } int GetLPAccurateYPos(int *pProject, int PrjLen, int *pUpYPos, int *pDownYPos) { int x; int Temp, TempUp, TempDown; BOOL Flag; Flag = TRUE; Temp = 0; *pUpYPos = 0; *pDownYPos = 0; *(pProject+PrjLen-1) = 0; for (x=0; x<PrjLen; x++) { if (Flag && (*(pProject+x) != 0)) { TempUp = x; Flag = FALSE; } if ((!Flag) && (*(pProject+x) == 0)) { TempDown = x; Flag = TRUE; if (Temp < TempDown- TempUp) { *pUpYPos = TempUp; *pDownYPos = TempDown; Temp = TempDown - TempUp; } } } if ((*pDownYPos) <= (*pUpYPos)) return 0; return 1; } int GetLPCharPos(int *pCharCount, RECT LPCharRect[], PGrayImg pSrcImg) { int i, j, k, x, y; BOOL Flag, Flag1; int CharID; int avg; int TempLeft, TempRight; int Code[101]; int *pOutLineProject; int res = 0; pOutLineProject = (int*)malloc(pSrcImg->Width*sizeof(int)); res = OutLineProject(pOutLineProject, pSrcImg); if (0 == res) return 0; res = OutLineProjectFilter(pOutLineProject, pSrcImg->Width, pSrcImg->Height); if (0 == res) return 0; Flag = TRUE; CharID = 0; *(pOutLineProject+pSrcImg->Width-1) = 0; for (i=0; i<pSrcImg->Width; i++) { if ((*(pOutLineProject+i) != 0) && Flag) { LPCharRect[CharID].left = i; LPCharRect[CharID].top = 0; LPCharRect[CharID].bottom = pSrcImg->Height - 1; Flag = FALSE; avg = 0; } if ((*(pOutLineProject+i) == 0) && (!Flag)) { LPCharRect[CharID].right = i; for (j=LPCharRect[CharID].left; j<=LPCharRect[CharID].right; j++) { avg += *(pOutLineProject+j); } avg = (int)(avg*1.0/(LPCharRect[CharID].right-LPCharRect[CharID].left)+0.5); if (!((LPCharRect[CharID].right-LPCharRect[CharID].left<(int)(0.2*pSrcImg->Height+0.5)) && (avg < (int)(0.5*pSrcImg->Height+0.5)))) { if (LPCharRect[CharID].right-LPCharRect[CharID].left > (int)(0.05*pSrcImg->Height+0.5)) { if (LPCharRect[CharID].right-LPCharRect[CharID].left < (int)(0.25*pSrcImg->Height+0.5)) { avg = 0; for (x=0; x<pSrcImg->Height; x++) for (y=LPCharRect[CharID].left; y<=LPCharRect[CharID].right; y++) { if (*(pSrcImg->pImg+x*pSrcImg->Width+y) == 255) avg++; } if (1.0*avg/(LPCharRect[CharID].right-LPCharRect[CharID].left)/pSrcImg->Height > 0.6) CharID++; } else CharID++; } } if (CharID > MAX_LPCHAR_CURRENT_COUNT-1) break; Flag = TRUE; } } Flag = TRUE; Flag1 = TRUE; k = 0; if (LPCharRect[CharID-1].right-LPCharRect[0].left < (int)(4.3*pSrcImg->Height+0.5)) { for (i=0; i<pSrcImg->Width; i++) { if ((*(pOutLineProject+i) != 0) && Flag1) Flag1 = FALSE; if ((*(pOutLineProject+i) == 0) && (!Flag1)) { TempLeft = i; Flag1 = TRUE; Flag = FALSE; } if ((*(pOutLineProject+i) != 0) && (!Flag)) { TempRight = i; if (TempRight-TempLeft < (int)(0.26*pSrcImg->Height+0.5)) Code[k] = 0; else Code[k] = 1; k++; if (k > 100) return 0; Flag = TRUE; } } if (Code[0] != 0) { if (CharID > MAX_LPCHAR_CURRENT_COUNT-1) CharID--; } else { if ((Code[1] == 1) && (CharID < MAX_LPCHAR_CURRENT_COUNT)) CharID++; } } for (i=CharID-1; i>=1; i--) { if (LPCharRect[i].right-LPCharRect[i].left < (int)(0.2*pSrcImg->Height+0.5)) { if (LPCharRect[i].left-LPCharRect[i-1].right < (int)(0.22*pSrcImg->Height+0.5)) CharID--; } else break; } if (LPCharRect[CharID-1].right-LPCharRect[CharID-1].left > (int)(0.5*pSrcImg->Height+0.5)) { if (LPCharRect[CharID-1].left+(int)(0.5*pSrcImg->Height+0.5)<pSrcImg->Width-1) { LPCharRect[CharID-1].right = LPCharRect[CharID-1].left+(int)(0.5*pSrcImg->Height+0.5); } else LPCharRect[CharID-1].right = pSrcImg->Width - 1; } *pCharCount = CharID; if (pOutLineProject != NULL) { free(pOutLineProject); pOutLineProject = NULL; } return 1; } int OutLineProject(int *pProject, PGrayImg pSrcImg) { int i, j, HighP, LowP; for (j=0; j<pSrcImg->Width; j++) { HighP = pSrcImg->Height; LowP = pSrcImg->Height; for (i=0; i<pSrcImg->Height; i++) { if (*(pSrcImg->pImg+i*pSrcImg->Width+j) > 0) { HighP = i; break; } } for (i=pSrcImg->Height-1; i>=0; i--) { if (*(pSrcImg->pImg+i*pSrcImg->Width+j) > 0) { LowP = i; break; } } *(pProject+j) = LowP - HighP; } *(pProject+pSrcImg->Width-1) = 0; return 1; } int OutLineProjectFilter(int *pProject, int PrjLen, int LPHeight) { int i, CharID, j; int Temp; int MergeID[101], TempWidth[101]; RECT LPCharRect[101]; BOOL Flag; *(pProject+PrjLen-1) = 0; Flag = TRUE; for (i=0; i<PrjLen; i++) { if ((*(pProject+i) != 0) && Flag) { Temp = i; Flag = FALSE; } if ((*(pProject+i) == 0) && (!Flag)) { if (i-Temp < (int)(0.2*LPHeight+0.5)) { for (j=Temp; j<i; j++) { if ((*(pProject+j)<(int)(0.5*LPHeight+0.5)) || (i-Temp<(int)(0.05*LPHeight+0.5))) *(pProject+j) = 0; } } Flag = TRUE; } } Flag = FALSE; for (i=0; i<PrjLen-1; i++) { if (*(pProject+i) < 2) *(pProject+i) = 0; if ((*(pProject+i) < *(pProject+i+1)) && Flag) { if (*(pProject+i) < (int)(0.3*LPHeight+0.5)) *(pProject+i) = 0; Flag = FALSE; } if ((*(pProject+i) > *(pProject+i+1)) && (!Flag)) Flag = TRUE; } Flag = TRUE; CharID = 0; for (i=0; i<PrjLen; i++) { if ((*(pProject+i) != 0) && Flag) { LPCharRect[CharID].left = i; Flag = FALSE; } if ((*(pProject+i) == 0) && (!Flag)) { LPCharRect[CharID].right = i - 1; TempWidth[CharID] = LPCharRect[CharID].right - LPCharRect[CharID].left + 1; if (TempWidth[CharID] < 2) { for (j=LPCharRect[CharID].left; j<=LPCharRect[CharID].right; j++) *(pProject+j) = 0; } else CharID++; if (CharID > 100) return 0; Flag = TRUE; } } j = 0; for (i=0; i<CharID; i++) { if (TempWidth[i] < (int)(0.4 * LPHeight + 0.5)) { MergeID[j] = i; j++; } if ((i==CharID-1) || (TempWidth[i]>=(int)(0.4*LPHeight+0.5))) { switch (j) { case 1: if (MergeID[0] < CharID - 1) { if (1 == IsChar(LPCharRect[MergeID[0]].left, LPCharRect[MergeID[0]+1].right, LPHeight)) if (LPCharRect[MergeID[0]+1].left-LPCharRect[MergeID[0]].right <= 4) *(pProject+LPCharRect[MergeID[0]].right+1) = 20; } if (MergeID[0] > 0) { if (1 == IsChar(LPCharRect[MergeID[0]-1].left, LPCharRect[MergeID[0]].right, LPHeight)) if (LPCharRect[MergeID[0]].left - LPCharRect[MergeID[0] - 1].right <= 4) *(pProject+LPCharRect[MergeID[0]].right+1) = 20; } break; case 2: Merge2(pProject, PrjLen, LPCharRect, MergeID, 0, 1, LPHeight); break; case 3: Merge3(pProject, PrjLen, LPCharRect, MergeID, 0, 2, LPHeight); break; case 4: Merge4(pProject, PrjLen, LPCharRect, MergeID, 0, 3, LPHeight); break; case 5: Merge5(pProject, PrjLen, LPCharRect, MergeID, 0, 4, LPHeight); break; case 6: case 7: case 8: case 9: case 10: case 11: Merge6(pProject, PrjLen, LPCharRect, MergeID, 0, 5, LPHeight); break; } j = 0; } } return 1; } int Merge2(int *pProject, int PrjLen, RECT LPCharRect[], int MergeID[], int StartID, int EndID, int CharHeight) { int p; BOOL Flag; if (1 == IsChar(LPCharRect[MergeID[StartID]].left, LPCharRect[MergeID[EndID]].right, CharHeight)) { Flag = TRUE; for (p=StartID; p<EndID; p++) { if (LPCharRect[MergeID[StartID+1]].left-LPCharRect[MergeID[StartID]].right>(int)(0.15*CharHeight+0.5)) Flag = FALSE; } if (Flag) { for (p=LPCharRect[MergeID[StartID]].left; p<=LPCharRect[MergeID[EndID]].right; p++) *(pProject+p) = (int)(CharHeight * 0.8 + 0.5); } else return 0; } else return 0; return 1; } int Merge3(int *pProject, int PrjLen, RECT LPCharRect[], int MergeID[], int StartID, int EndID, int CharHeight) { if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID, CharHeight)) if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 1, CharHeight)) if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 1, EndID, CharHeight)) return 0; return 1; } int Merge4(int *pProject, int PrjLen, RECT LPCharRect[], int MergeID[], int StartID, int EndID, int CharHeight) { if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID, CharHeight)) if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 1, CharHeight)) if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 1, EndID, CharHeight)) if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 2, CharHeight)) Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 2, EndID, CharHeight); else { if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 1, EndID - 1, CharHeight)) if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 2, EndID, CharHeight)) return 0; } return 1; } int Merge5(int *pProject, int PrjLen, RECT LPCharRect[], int MergeID[], int StartID, int EndID, int CharHeight) { if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID, CharHeight)) if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 1, CharHeight)) if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 1, EndID, CharHeight)) if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 2, CharHeight)) Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 3, EndID, CharHeight); else { if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 1, EndID - 1, CharHeight)) if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 2, EndID, CharHeight)) Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 3, CharHeight); else { if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 3, CharHeight)) Merge3(pProject, PrjLen, LPCharRect, MergeID, StartID + 2, EndID, CharHeight); else { if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 1, EndID - 2, CharHeight)) Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 3, EndID, CharHeight); else { if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 2, EndID - 1, CharHeight)) Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 3, CharHeight); else { if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 3, EndID, CharHeight)) if (0 == Merge3(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 2, CharHeight)) return 0; } } } } } return 1; } int Merge6(int *pProject, int PrjLen, RECT LPCharRect[], int MergeID[], int StartID, int EndID, int CharHeight) { if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID, CharHeight)) if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 1, CharHeight)) if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 1, EndID, CharHeight)) if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 2, CharHeight)) Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 4, EndID, CharHeight); else { if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 1, EndID - 1, CharHeight)) if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 2, EndID, CharHeight)) Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 4, CharHeight); else { if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 3, CharHeight)) Merge3(pProject, PrjLen, LPCharRect, MergeID, StartID + 3, EndID, CharHeight); else { if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 1, EndID - 2, CharHeight)) Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 4, EndID, CharHeight); else { if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 2, EndID - 1, CharHeight)) Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 4, CharHeight); else { if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 3, EndID, CharHeight)) Merge3(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 3, CharHeight); else { if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 4, CharHeight)) Merge4(pProject, PrjLen, LPCharRect, MergeID, StartID + 2, EndID, CharHeight); else { if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 1, EndID - 3, CharHeight)) Merge3(pProject, PrjLen, LPCharRect, MergeID, StartID + 3, EndID, CharHeight); else { if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 2, EndID - 2, CharHeight)) { Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 4, CharHeight); Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 4, EndID, CharHeight); } else { if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 3, EndID - 1, CharHeight)) Merge3(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 3, CharHeight); else { if (1 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID + 4, EndID, CharHeight)) if (0 == Merge2(pProject, PrjLen, LPCharRect, MergeID, StartID, EndID - 2, CharHeight)) return 0; } } } } } } } } } } return 1; } int Merge7(int *pProject, int PrjLen, RECT LPCharRect[], int MergeID[], int StartID, int EndID, int CharHeight) { return 1; } int Merge8(int *pProject, int PrjLen, RECT LPCharRect[], int MergeID[], int StartID, int EndID, int CharHeight) { return 1; } int IsChar(int CharLeft, int CharRight, int CharHeight) { int res = 0; if ((CharRight-CharLeft>(int)(0.30*CharHeight+0.5)) && (CharRight-CharLeft<(int)(0.6*CharHeight+0.5))) res = 1; else res = 0; return res; } int ReadParam(char *szFileName) { _finddata_t fileinfo; long lres; lres = _findfirst(szFileName, &fileinfo); if (-1 != lres) { g_LPHeight = GetPrivateProfileInt("GDCLPRINI", "LPHeight", 80, szFileName); g_LPWidth = GetPrivateProfileInt("GDCLPRINI", "LPWidth", 220, szFileName); g_LPAccurateHeight = GetPrivateProfileInt("GDCLPRINI", "LPAccurateHeight", 40, szFileName);; g_Threshold = GetPrivateProfileInt("GDCLPRINI", "Threshold", 160, szFileName); g_Threshold_HLP = GetPrivateProfileInt("GDCLPRINT", "Threshold_HLP", 100, szFileName); g_LeftOffset = GetPrivateProfileInt("GDCLPRINI", "LeftOffset", 0, szFileName); g_RightOffset = GetPrivateProfileInt("GDCLPRINI", "RightOffset", 0, szFileName); g_TopOffset = GetPrivateProfileInt("GDCLPRINI", "TopOffset", 0, szFileName); g_BottomOffset = GetPrivateProfileInt("GDCLPRINI", "BottomOffset", 0, szFileName); } return 1; } int SaveParam(int LPHeight, int LPWidth, int LPAccurateHeight, int Threshold, int Threshold_HLP, int LeftOffset, int RightOffset, int TopOffset, int BottomOffset, char *szFileName) { char str[255]; sprintf(str, "%d", LPHeight); WritePrivateProfileString("GDCLPRINI", "LPHeight", str, szFileName); sprintf(str, "%d", LPWidth); WritePrivateProfileString("GDCLPRINI", "LPWidth", str, szFileName); sprintf(str, "%d", LPAccurateHeight); WritePrivateProfileString("GDCLPRINI", "LPAccurateHeight", str, szFileName); sprintf(str, "%d", Threshold); WritePrivateProfileString("GDCLPRINI", "Threshold", str, szFileName); sprintf(str, "%d", Threshold_HLP); WritePrivateProfileString("GDCLPRINI", "Threshold_HLP", str, szFileName); sprintf(str, "%d", LeftOffset); WritePrivateProfileString("GDCLPRINI", "LeftOffset", str, szFileName); sprintf(str, "%d", RightOffset); WritePrivateProfileString("GDCLPRINI", "RightOffset", str, szFileName); sprintf(str, "%d", TopOffset); WritePrivateProfileString("GDCLPRINI", "TopOffset", str, szFileName); sprintf(str, "%d", BottomOffset); WritePrivateProfileString("GDCLPRINI", "BottomOffset", str, szFileName); return 1; } RECT GetManualCutRect(int *pLeftOffset, int *pRightOffset, int *pTopOffset, int *pBottomOffset, int OriWidth, int OriHeight) { RECT CutRect; *pLeftOffset = g_LeftOffset; *pRightOffset = g_RightOffset; *pTopOffset = g_TopOffset; *pBottomOffset = g_BottomOffset; CutRect.left = g_LeftOffset; CutRect.top = g_TopOffset; CutRect.right = OriWidth - g_RightOffset - 1; CutRect.bottom = OriHeight - g_BottomOffset - 1; return CutRect; }