| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 792 人关注过本帖, 1 人收藏
标题:车牌识别之锁定文字范围
只看楼主 加入收藏
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:750
专家分:1114
注 册:2021-10-13
结帖率:96.55%
收藏(1)
已结贴  问题点数:20 回复次数:7 
车牌识别之锁定文字范围
终于有时间把车牌识别的文字范围确定下来了。但是发现对图片数据流的分析,发现图片数据流在显示器上显示的时候,数据还是有点差异,却不知道产生这个差异的原因。
不管怎样先把代码发上来,希望各位大侠帮忙分析一下原因。

二级化的代码是吹版提供的,在此表示鸣谢!
程序代码:
**************************************************
*-- 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

运行后的效果图如下:
图片附件: 游客没有浏览图片的权限,请 登录注册
搜索更多相关主题的帖子: thisform Left long 像素 Top 
2023-02-25 15:24
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:750
专家分:1114
注 册:2021-10-13
收藏
得分:0 
找到问题所在,已解决!
2023-02-26 13:05
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:335
帖 子:9828
专家分:27146
注 册:2012-2-5
收藏
得分:5 

坚守VFP最后的阵地
2023-02-26 13:08
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:750
专家分:1114
注 册:2021-10-13
收藏
得分:0 
需要源码的那位兄弟,我只是阶段性完成,请耐心等候,你可以关注我,我完成了会更新在论坛里的。

我是业余爱好,兼职写着玩,所以可能要等哦。
2023-02-27 12:27
sostemp
Rank: 4
等 级:贵宾
威 望:10
帖 子:202
专家分:284
注 册:2009-6-2
收藏
得分:5 
2023-02-27 16:42
dlacs
Rank: 1
等 级:新手上路
帖 子:5
专家分:8
注 册:2021-4-2
收藏
得分:5 
回复 4楼 sam_jiang
厉害,期待!
2023-02-27 20:55
schtg
Rank: 12Rank: 12Rank: 12
来 自:Usa
等 级:贵宾
威 望:67
帖 子:1604
专家分:3144
注 册:2012-2-29
收藏
得分:5 
期待...
2023-02-27 21:25
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:750
专家分:1114
注 册:2021-10-13
收藏
得分:0 
目前只完成到分割每个字符。
2023-02-28 00:40
快速回复:车牌识别之锁定文字范围
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.025175 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved