正文

简单的文字识别 源代码2006-09-28 21:58:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/embed/18920.html

分享到:

想要一个简单的文字识别vc源代码,从黑白图像中识别出文字,就是背景是白色,文字是黑色。只需简单识别英文26个大小写字母就够了。 
--------------------------------------------------------------------------------
 本回复被接受作为正确答案


   做过类似的程序,用摄像头采集类似于电话充值卡的图象,对其的卡号,密码区域进行识别,只识别数字。(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);   
}
 
希望能对你有所帮助!

阅读(7779) | 评论(4)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册