正文

简单的文字识别 源代码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);    }  希望能对你有所帮助!

阅读(7844) | 评论(4)


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

评论

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