车牌识别之锁定文字范围
终于有时间把车牌识别的文字范围确定下来了。但是发现对图片数据流的分析,发现图片数据流在显示器上显示的时候,数据还是有点差异,却不知道产生这个差异的原因。不管怎样先把代码发上来,希望各位大侠帮忙分析一下原因。
二级化的代码是吹版提供的,在此表示鸣谢!
程序代码:
************************************************** *-- Form: form1 (d:\documents\visual foxpro 项目\cpsb.scx) *-- ParentClass: form *-- BaseClass: form *-- Time Stamp: 02/25/23 02:51:06 PM * DEFINE CLASS form1 AS form Top = 0 Left = 0 Height = 716 Width = 984 DoCreate = .T. Caption = "Form1" FontSize = 12 Name = "Form1" ADD OBJECT image1 AS image WITH ; Picture = "原图.jpg", ; Height = 50, ; Left = 125, ; Top = 42, ; Width = 230, ; Name = "Image1" ADD OBJECT label1 AS label WITH ; AutoSize = .T., ; FontSize = 12, ; Caption = "原图", ; Height = 20, ; Left = 225, ; Top = 17, ; Width = 34, ; Name = "Label1" ADD OBJECT image2 AS image WITH ; Picture = "", ; Height = 50, ; Left = 549, ; Top = 42, ; Width = 230, ; Name = "Image2" ADD OBJECT image3 AS image WITH ; Picture = "", ; Height = 50, ; Left = 125, ; Top = 221, ; Width = 230, ; Name = "Image3" ADD OBJECT image4 AS image WITH ; Picture = "", ; Height = 50, ; Left = 550, ; Top = 221, ; Width = 230, ; Name = "Image4" ADD OBJECT command1 AS commandbutton WITH ; AutoSize = .T., ; Top = 15, ; Left = 634, ; Height = 25, ; Width = 72, ; Caption = "生成灰阶图", ; Name = "Command1" ADD OBJECT command2 AS commandbutton WITH ; AutoSize = .T., ; Top = 190, ; Left = 210, ; Height = 25, ; Width = 72, ; Caption = "生成黑白图", ; Name = "Command2" ADD OBJECT command3 AS commandbutton WITH ; AutoSize = .F., ; Top = 190, ; Left = 629, ; Height = 25, ; Width = 84, ; Caption = "框选文字范围", ; Name = "Command3" ADD OBJECT label2 AS label WITH ; Caption = "Label2", ; Height = 16, ; Left = 530, ; Top = 200, ; Width = 38, ; Name = "Label2" ADD OBJECT label3 AS label WITH ; Caption = "Label2", ; Height = 16, ; Left = 761, ; Top = 272, ; Width = 38, ; Name = "Label3" PROCEDURE command1.Click huijie(thisform.image1.Picture,"灰阶.bmp") thisform.image2.Picture="灰阶.bmp" ENDPROC PROCEDURE command2.Click quzao1(thisform.image1.Picture,"黑白.bmp") thisform.image3.Picture="黑白.bmp" thisform.image4.Picture="黑白.bmp" ENDPROC PROCEDURE command3.Click noldcolor=thisform.ForeColor thisform.ForeColor=RGB(255,0,0) cstr=FILETOSTR(thisform.image4.Picture) &&图像文件流 colordata=right(cstr,LEN(cstr)-54) &&提取图像像素数据 ****将图像数据转换为一个长为image4.width,宽为image4.height的由0和1组成的矩阵******** colordata=STRTRAN(colordata,REPLICATE(CHR(0),3)+CHR(255),"1") &&将黑色像素转换为1 colordata=STRTRAN(colordata,REPLICATE(CHR(255),3)+CHR(255),"0") &&将白色像素转换为0 ********************************************************************************** LOCAL nposition,nleft,ntop,nright,nbottom,nx,ny,colordata1,x,y nx=thisform.image4.Width ny=thisform.image4.height nposition=AT("1",colordata,1) &&定位第一个黑色像素的位置 ntop=INT(nposition/nx) &&确定第一个黑色像素所在行 nposition=rAT("1",colordata,1) &&定位倒数第一个黑色像素的位置 nbottom=CEILING(nposition/nx) &&确定最后一个黑色像素所在行 ****************************************转换矩阵********************************************** colordata1="" FOR j=1 TO nx FOR i=1 TO ny colordata1=colordata1+SUBSTR(colordata,nx*(i-1)+j,1) ENDFOR ENDFOR *********************得到一个翻转的像素矩阵,以确定最左侧的黑色像素位置************************** nposition=AT("1",colordata1,1) &&定位第一个黑色像素的位置 nleft=INT(nposition/ny) &&确定第一个黑色像素所在行,即第一个矩阵所在的列 nposition=rAT("1",colordata1,1) &&定位第一个黑色像素的位置 nright=INT(nposition/ny) &&确定倒数第一个黑色像素所在行,即第一个矩阵所在的列 x=thisform.image4.Left y=thisform.image4.Top thisform.Box(x+nleft,y+ntop-1,x+nright+1,y+nbottom+1) *!* WITH thisform.image4 *!* thisform.Line(.left,.top+9,.left+.width,.top+9) *!* thisform.Line(.left,.top+39,.left+.width,.top+39) *!* thisform.Line(.left+13,.top,.left+13,.top+.height) *!* thisform.Line(.left+48,.top,.left+48,.top+.height) *!* thisform.Line(.left+69,.top,.left+69,.top+.height) *!* thisform.Line(.left+83,.top,.left+83,.top+.height) *!* thisform.Line(.left+93,.top,.left+93,.top+.height) *!* thisform.Line(.left+107,.top,.left+107,.top+.height) *!* thisform.Line(.left+127,.top,.left+127,.top+.height) *!* thisform.Line(.left+144,.top,.left+144,.top+.height) *!* thisform.Line(.left+164,.top,.left+164,.top+.height) *!* thisform.Line(.left+184,.top,.left+184,.top+.height) *!* thisform.Line(.left+199,.top,.left+199,.top+.height) *!* thisform.Line(.left+.width-10,.top,.left+.width-10,.top+.height) *!* ENDWITH thisform.ForeColor=noldcolor ENDPROC PROCEDURE label2.Init this.AutoSize=.t. this.Caption="("+TRANSFORM(thisform.image4.Left)+","+TRANSFORM(thisform.image4.Top)+")" ENDPROC PROCEDURE label3.Init this.AutoSize=.t. this.Caption="("+TRANSFORM(thisform.image4.Left+thisform.image4.width)+","+TRANSFORM(thisform.image4.Top+thisform.image4.height)+")" ENDPROC ENDDEFINE * *-- EndDefine: form1 **************************************************
二级化代码
quzao1.prg
程序代码:
PARAMETERS infile, outfile IF PARAMETERS()=0 cDefPath = ADDBS(JUSTPATH(SYS(16))) SET DEFAULT TO (cDefPath) ** 输入/输出文件 inFile = cDefPath + "test.png" outFile = cDefPath + "test.bmp" ENDIF DECLARE long GdiplusStartup IN gdiplus long@,string@,long DECLARE long GdiplusShutdown IN gdiplus long DECLARE long GdipCreateBitmapFromScan0 IN gdiplus long,long,long,long,string@,long@ DECLARE long GdipGetImageGraphicsContext IN gdiplus long,long@ DECLARE long GdipLoadImageFromFile IN gdiplus string@,long@ DECLARE long GdipGetImageWidth IN gdiplus long,long@ DECLARE long GdipGetImageHeight IN gdiplus long,long@ DECLARE long GdipSaveImageToFile IN gdiplus long,string@,string@,long DECLARE long GdipDrawImageRectI IN gdiplus long,long,long,long,long,long DECLARE long GdipDisposeImage IN gdiplus long DECLARE long GdipDeleteGraphics IN gdiplus long DECLARE long GdipBitmapLockBits IN GDIPLUS long, string@, long, long, string@ DECLARE long GdipBitmapUnlockBits IN GDIPLUS long, string@ DECLARE long GdipCreateFromHDC IN gdiplus long,long@ DECLARE long GetDC IN user32 long DECLARE long ReleaseDC IN user32 long,long #define ImageLockModeReadWrite 0x0003 #define PixelFormat_32bppARGB 0x0026200A ** 初始化GDI stGSI = 0h01000000000000000000000000000000 pGDI = 0 GdiplusStartup(@pGDI, @stGSI, 0) ** 载入文件 pImage = 0 GdipLoadImageFromFile(STRCONV(inFile+0h00,5), @pImage) nWidth = 0 nHeight = 0 GdipGetImageWidth(pImage, @nWidth) GdipGetImageHeight(pImage, @nHeight) ** 统一转换为32位ARGB格式 pBitmap = 0 GdipCreateBitmapFromScan0(nWidth, nHeight, 0, PixelFormat_32bppARGB, 0, @pBitmap) pGraphics = 0 GdipGetImageGraphicsContext(pBitmap, @pGraphics) GdipDrawImageRectI(pGraphics, pImage, 0, 0, nWidth, nHeight) GdipDisposeImage(pImage) ** 获取缓存图像数据地址和大小 stRct = REPLICATE(0h00,8) + BINTOC(nWidth,"4rs") + BINTOC(nHeight,"4rs") stBmpData = REPLICATE(0h00, 24) && BITMAPDATA 结构 GdipBitmapLockBits(pBitmap, @stRct, ImageLockModeReadWrite, PixelFormat_32bppARGB, @stBmpData) pData = CTOBIN(SUBSTR(stBmpData,17,4),"4rs") && 图像数据首址 nCount = nWidth * nHeight * 4 && 图像数据字总节数(32位4字节) ** 转换图像数据 Gray(pData, nCount) && 灰度化 Binary(pData, nCount) && 二值化 GdipBitmapUnlockBits(pBitmap, @stBmpData) &&更新数据 ** 输出文件 CLSID_BMP = 0h00F47C55041AD3119A730000F81EF32E GdipSaveImageToFile(pBitmap, STRCONV(outFile+0h00,5), CLSID_BMP, 0) GdipDeleteGraphics(pGraphics) GdipDisposeImage(pBitmap) ** 显示图片 DrawImageWindowFromFile(_screen.hWnd, 10, 10, nWidth, nHeight, outFile) GdiplusShutdown(pGDI) *CLEAR ALL RETURN ** 灰度化 FUNCTION Gray(pData, nCount) FOR i=0 TO nCount-1 STEP 4 avg = 0.114 * ASC(SYS(2600,pData+i,1)); + 0.587 * ASC(SYS(2600,pData+i+1,1)); + 0.299 * ASC(SYS(2600,pData+i+2,1)) avg = INT(avg) SYS(2600,pData+i,3,CHR(avg)+CHR(avg)+CHR(avg)) ENDFOR ENDFUNC ** 二值化 FUNCTION Binary(pData, nCount) * 计算阈值 k1 = 127 && 随机取0~255 k2 = 0 DO WHILE k1 != k2 k2 = k1 avgPix = 0 avgBac = 0 avgPixCnt = 0 FOR i=0 TO nCount-1 STEP 4 FOR j=i TO i+2 && R、G、B,不考虑A ki = ASC(SYS(2600,pData+j,1)) IF ki < k2 avgPix = avgPix + ki && 像素数据 avgPixCnt = avgPixCnt + 1 ELSE avgBac = avgBac + ki && 背景数据 ENDIF ENDFOR ENDFOR avgPix = INT(avgPix / avgPixCnt) avgBac = INT(avgBac / (nCount-avgPixCnt)) k1 = INT((avgPix+avgBac) / 2) ENDDO * 二值化 FOR i=0 TO nCount-1 STEP 4 FOR j=i TO i+2 ki = IIF(ASC(SYS(2600,pData+j,1)) < k1, 0, 255) SYS(2600, pData+j, 1, CHR(ki)) ENDFOR ENDFOR ENDFUNC ** 显示图片 FUNCTION DrawImageWindowFromFile(hWnd, nX, nY, nWidth, nHeight, cFileName) LOCAL hDC, pImage, pGraphics pImage = 0 GdipLoadImageFromFile(STRCONV(cFileName+0h00,5), @pImage) hDC = GetDC(hWnd) pGraphics = 0 GdipCreateFromHDC(hDC, @pGraphics) GdipDrawImageRectI(pGraphics, pImage, nX, nY, nWidth, nHeight) GdipDisposeImage(pImage) GdipDeleteGraphics(pGraphics) ReleaseDC(hWnd, hDC) ENDFUNC
运行后的效果图如下: