风中的流沙

萋萋少年讨江湖,亦真亦幻总虚度。风卷流沙落天涯,缘起缘灭任追逐。

导航

<2008年8月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456

统计

留言簿(94)

随笔档案

文章档案

相关链接

搜索

最新评论

阅读排行榜

评论排行榜

简单文字识别vc代码(来自vchelp)

想要一个简单的文字识别vc源代码,从黑白图像中识别出文字,就是背景是白色,文字是黑色。只需简单识别英文26个大小写字母就够了。

jinzuo007
jinzuo
第1楼 回复于2003-4-11 18:07:38 给会员jinzuo007留言
本回复被接受本回复被接受作为正确答案


To xujianfeng:
   我做过类似的程序,用摄像头采集类似于电话充值卡的图象,对其的卡号,密码区域进行识别,只识别数字。(0-9)但原理相同,你只需改一下字库即可使用。
   我先说下步骤:
   1. 字符和字符之间都有间隔,首先要根据间隔确定每个字符的区域(Rect).
   2. 然后一个一个象素地和标准字符比较。也就是比较 26 * 2 = 52 次,误差最小的,就认为是该字符。
(注:这种算法比较简单,易于理解,缺点就是效率不高,我用摄像头采集图象识别数字成功率为 98%以上。我曾请教过一位做这方面的专家,他称无论什么识别,影响识别的最重要因数就是源图象的质量。如果识别率不到 90% 请你仔细考虑源图象的采集质量,并重新考虑该方法的可行性。)
   附代码如下:

/** 取得每个字符的边界***/
void CPOCRNuberDlg::GetCharRect(HBITMAP bit, RECT rect,int type, CDC* pDC )
{
    CString strTemp2;
    CBitmap bitmap;
    bitmap.m_hObject = CopyImage(bit,IMAGE_BITMAP,0,0,LR_MONOCHROME);

    //CDC *pDC = GetDC();
    CDC mDC;
    
    mDC.CreateCompatibleDC( pDC );
    mDC.SetBoundsRect( &rect, DCB_RESET);
    mDC.SelectObject(bitmap.m_hObject);

    BOOL bIsChar = false;
    corInfo = new OCR_Info[50];
    int index  = 0;

    COLORREF colPix;
    int        iR;
    int        iG;

/**************  取出每个数字所占的Rect  **************/
// 列扫描

    CString str;
    for (int i = rect.left; i < rect.right ; i++)
    {
        for (int j = rect.top - 250 ; j < rect.bottom - 250; j++)
        {
            colPix = mDC.GetPixel(i,j);
            iG = GetGValue(colPix);
            
            // 字符开始
            if ( (iG == 0) && (!bIsChar) )
            {
                corInfo[index].rect.left = i;
                corInfo[index].Index = index;
                bIsChar = true;
                
                break;
            }
            // 字符继续
            else if ((iG == 0) && (bIsChar))
            {
                break;
            }
            // 字符结束
            else if ((iG == 255) && ( j > rect.bottom  -252) && (bIsChar))
            {
                corInfo[index].rect.right = i-1;
                if ((corInfo[index].rect.right - corInfo[index].rect.left) > 3)
                    index++;
                bIsChar = false;
                break;
            }
            
        }    
    }

    CClientDC lDC(this);
    
// 行扫描
    bIsChar = false;
    int iBZ =0;
    for ( int iinx = 0; iinx < index; iinx++)
    {
        for (int ii = rect.top-250 ; ii < rect.bottom -250; ii++)
        {
            for (int j = corInfo[iinx].rect.left ; j < corInfo[iinx].rect.right ; j++)
            {
                colPix = mDC.GetPixel(j,ii);                
                iG = GetGValue(colPix);                            
                // 字符顶端开始
                if ( (iG == 0) && (!bIsChar) )
                {
                    corInfo[iinx].rect.top = ii;                    
                    bIsChar = true;                
                    break;                
                }
                // 字符继续
                else if ((iG == 0) && (bIsChar))
                {
                    break;
                }
                // 字符底端结束
                else if ((iG == 255) && ( j > corInfo[iinx].rect.right -2 ) && (bIsChar))
                {            
                    corInfo[iinx].rect.bottom  = ii-1;                
                    bIsChar = false;
                    break;
                }                
            }            
        }
    }

/******  位置确定完成,每个字符的位置信息写在 corInfo.rect 中********/

    char m_pFilePath[255];
    CStdioFile fInfo;

    strcpy(m_pFilePath,"D:\\info.ini");
    fInfo.Open( m_pFilePath, CFile::modeCreate | CFile::modeWrite );

    CDC  NewDC;    
    NewDC.CreateCompatibleDC(pDC);
    CBitmap memBmp;
    memBmp.CreateCompatibleBitmap( &mDC, 14, 20 );
    NewDC.SelectObject( memBmp );
/*    
// 标志定义
    iBZ =0;
    BOOL bBZ = false;    

    
    for (int bn = 0; bn<index; bn++)
    {
        NewDC.StretchBlt( 0,0,14,20,
                        &mDC,corInfo[bn].rect.left +1,
                        corInfo[bn].rect.top +1,
                        corInfo[bn].rect.right - corInfo[bn].rect.left -1,
                        corInfo[bn].rect.bottom - corInfo[bn].rect.top -1,
                        SRCCOPY);

        
        for (int yy = 0; yy <20; yy ++)
        {
            for (int xx = 0; xx <14;xx++)
            {
                colPix = NewDC.GetPixel(xx,yy);
                iR = GetRValue(colPix);    
                if (iR == 255)
                    str = "□";
                else
                    str ="■";
                fInfo.WriteString(str);
            }
            fInfo.WriteString("\n");
        }
        str.Format("NEXT%d\n",bn);
        fInfo.WriteString(str);
    }
/************************** OCR **************************/
    CString strField;
    CString strtemp;
    char cNum[281];
    int iNumIndex = 0;
    int iErrCount[10];
    int iECount =0;
    int iBlack = 0;
    int idx = 0;
    int ww =0;
    int w = 0;
    
    GetCurrentDirectory(255,m_pFilePath);
    strcat(m_pFilePath,HOCRINI);
    //strcat(m_pFilePath,"\\stdinfo.ini");
// 逐个扫描,识别    
    for (int l = 0; l<index; l++)
    {    
        NewDC.StretchBlt( 0,0,14,20,
                        &mDC,corInfo[l].rect.left +1,
                        corInfo[l].rect.top +1,
                        corInfo[l].rect.right - corInfo[l].rect.left -1,
                        corInfo[l].rect.bottom - corInfo[l].rect.top -1,
                        SRCCOPY);        

        for (w = 0 ;w< 10; w++)
            iErrCount[w] = 0;

        for (int itmp = 0; itmp < 10; itmp++)
        {
            strtemp.Format("%d",itmp);
            GetPrivateProfileString("Number",strtemp,"",
                        cNum,281,m_pFilePath);
            for(int iy = 0; iy < 20; iy ++)
            {
                for(int ix = 0; ix<14;ix++)
                {
                    colPix = NewDC.GetPixel(ix,iy);
                    iR = GetRValue(colPix);
                    if (iR == 255)
                        iR = 49;
                    else
                        iR = 48;
                    if ( iR != cNum[iNumIndex])
                        iErrCount[itmp]++;                    
                    iNumIndex++;                    
                }                
            }        
            iNumIndex = 0;            
        }
        iECount = iErrCount[0];
        idx = 0;
        for(ww =0; ww< 10; ww++)
        {
            if (iErrCount[ww] < iECount)
            {
                iECount = iErrCount[ww];
                idx = ww;
            }
        }
        // 区别1
        if (idx != 1)
        {
            for (int itx = 7; itx < 9; itx++)
            {
                for (int ity = 0; ity < 20; ity++)
                {
                    colPix = NewDC.GetPixel(itx,ity);
                    iR = GetRValue(colPix);
                    if (iR == 0)
                        iBlack++;
                }
            }
            if (iBlack > 39)
            {
                idx = 1;
            }
            iBlack = 0;
        }
        // 再将0 和8 进行判断
        if ((idx == 0) | (idx ==8))
        {
            for (int ity = 8; ity < 10; ity++)
            {
                for (int itx = 2; itx < 12; itx++)
                {
                    colPix = NewDC.GetPixel(itx,ity);
                    iR = GetRValue(colPix);
                    if (iR == 0)
                        iBlack++;
                }
            }
            if (iBlack > 14)
                idx = 8;
            else
                idx = 0;
            iBlack = 0;
        }
        // 再将5 和6 进行判断
        if (( idx == 5) | (idx == 6))
        {
            
        }
        str.Format("%d",idx);
        strTemp2 += str;
        /*
        if (type == 1)
            //m_CardNum += str;
        else
            //m_CardPWD += str;
        */
    }
    
/*****************************************/
    delete [] corInfo;    

    if (type == 1)
        m_ctrlCardNum.SetWindowText( strTemp2 );        
    else
        m_ctrlCardPWD.SetWindowText( strTemp2 );        
    //::ReleaseDC(m_hWnd,(HDC)pDC);
    //UpdateData(false);    
}
  
希望能对你有所帮助!

jinzuo007

------------------------签----名----
一直有梦想,一直没成功!
一直没成功,一直有梦想!

posted on 2005-03-11 09:21 风中的一粒流沙 阅读(5261) 评论(9)  编辑 收藏

评论

# re: 简单文字识别vc代码(来自vchelp) 2005-03-21 17:08 xinhe

good paper , I like it!

# re: 简单文字识别vc代码(来自vchelp) 2008-06-05 00:33 Fireli

me too

# zkbfyqhi 2008-06-09 19:57 zkbfyqhi

 zadjqavq http://dsqaqrxq.com wpgpztkr purkifij  [URL=http://boagmoca.com]sukknzuj[/URL]  <a href="http://fsujespw.com">jyutdhla</a> 

# re: 简单文字识别vc代码(来自vchelp) 2008-08-17 19:12 中彩网

友情内容:[url=http://www.csdddc.com]中彩网[/url]他对着[url=http://www.521241.cn]中彩网[/url]
的弟弟说,我要好好对你,[url=http://www.163y.com.cn]中彩网[/url]你一定要好好活下去啊,
真的[url=http://www.0746top.com]中彩网[/url]你一定要好好活下去,相信自己。

# re: 简单文字识别vc代码(来自vchelp) 2008-10-09 14:12 张天

[url=http://www.510868.com]中彩网[/url]
[url=http://www.1638866.com]中彩网[/url]
[url=http://www.haodasw.com]东方财富网[/url]
[url=http://www.6868552.com]中彩网[/url]
[url=http://www.sf365w.com]中彩网[/url]
[url=http://www.288427.com]中彩网[/url]
[url=http://www.88392.com]中国股票网[/url]
[url=http://www.dg6660.com]中彩网[/url]

# re: 简单文字识别vc代码(来自vchelp) 2008-10-09 14:13 张天


<a href="http://www.510868.com">中彩网</a> /
<a href="http://www.1638866.com">中彩网</a> /
<a href="http://www.haodasw.com">东方财富网</a> /
<a href="http://www.6868552.com">中彩网</a> /
<a href="http://www.sf365w.com">中彩网</a> /
<a href="http://www.288427.com">中彩网</a> /
<a href="http://www.88392.com">中国股票网</a> /
<a href="http://www.dg6660.com">中彩网</a> /

标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]