2012-01-02 99 views
8

我正在編寫OCR應用程序以從屏幕截圖圖像中讀取字符。目前,我只關注數字。我部分基於我的方法在這篇博文中:http://blog.damiles.com/2008/11/basic-ocr-in-opencv/來自屏幕截圖的低分辨率文本的OCR

我可以使用一些聰明的閾值成功地提取每個單獨的字符。有些棘手的地方是匹配字符。即使使用固定的字體和大小,也會有一些變量,例如背景顏色和字距,這些變量會導致相同的數字以不同的形狀出現。例如,下面的圖像分割成3個部分:

  1. 上:我成功地從截圖中提取的對象位的
  2. 中東:模板:從我訓練的一個數字設置
  3. 下圖:頂部和中間圖像之間的誤差(絕對差值)

零件已全部縮放(兩條綠色水平線之間的距離表示一個像素)。

topbottommiddle

你可以看到,儘管頂部和中間圖像清晰表示2,它們之間的誤差是相當高的。這會導致在匹配其他數字時出現誤報 - 例如,不難看出放置良好的7可以如何匹配圖像中的目標數字比中間圖像更好。

目前,我正在處理這個問題的方法是爲每個數字設置一堆訓練圖像,並將目標數字與這些圖像相匹配,一一對應。我嘗試了訓練集的平均圖像,但這並不能解決問題(其他數字上的誤報)。

我有點不願意使用移位模板執行匹配(它與我現在所做的基本相同)。有沒有比簡單的絕對差異更好地比較兩幅圖像的方法?我想到的可能是類似於2D中的EMD(推土機距離,http://en.wikipedia.org/wiki/Earth_mover's_distance):基本上,我需要一種比較方法,它不像全局移動和局部小變化那樣敏感(白色像素旁邊的像素變爲白色,或黑色像素旁邊的像素變爲黑色),但對全局變化敏感(黑色像素遠不及白色像素變爲黑色,反之亦然)。

任何人都可以提出一個比絕對差異更有效的匹配方法嗎?

我使用C風格的Python包裝(import cv)在OpenCV中完成所有這些工作。

回答

6

我會考慮使用哈爾瀑布。我用它們進行人臉檢測/頭部追蹤,似乎你可以用足夠的'2','3','4'等來建立一個相當不錯的級聯。

http://alereimondo.no-ip.org/OpenCV/34

http://en.wikipedia.org/wiki/Haar-like_features

+0

謝謝!我一定會看看哈爾瀑布。你認爲它將與簡單圖像減法相比有多高效?我預計它會變慢。但是,如果速度慢5倍,但取代10個圖像檢查以獲得相同的效果,那麼它肯定值得。 – misha 2012-01-02 05:03:38

+0

您必須生成級聯,這是一個非常耗時的過程(但也是愚蠢的可並行化)。它還需要大量的輸入數據(我會使用桌面上每種字體的數字)。 – rsaxvc 2012-01-02 05:17:04

+0

慢於減法,但您可以一次搜索特定級聯的所有實例的圖像。 – rsaxvc 2012-01-02 05:19:19

3

OCR在嘈雜的圖像是不容易的 - 這麼簡單的方法沒有效果不佳。

因此,我建議您使用HOG來提取要分類的特徵和SVM。 HOG似乎是描述形狀最有力的方法之一。

整個處理管道在OpenCV中實現,但我不知道python包裝中的函數名稱。你應該可以用最新的haartraining.cpp進行訓練 - 它實際上支持的不僅僅是haar - 還有HOG和LBP。

我認爲最新的代碼(來自主幹)比官方發佈(2.3.1)有了很大的改進。

HOG通常只需要其他識別方法使用的訓練數據的一小部分,但是,如果要對部分被遮擋(或缺失)的形狀進行分類,則應確保在訓練中包含一些這樣的形狀。

+0

我不會把圖像*吵雜*本身,但我看到你來自哪裏。我會看看HOG。謝謝。 – misha 2012-01-02 07:53:47

3

我可以從我的經驗和閱讀關於字符分類的幾篇論文告訴你,一個好的開始方法是閱讀主成分分析(PCA),Fisher線性判別分析(LDA)和支持向量機(支持向量機)。這些是對OCR非常有用的分類方法,事實證明OpenCV已經在PCAsSVMs中包含了出色的實現。我還沒有看到任何OCR的OpenCV代碼示例,但是您可以使用一些修改後的臉部分類版本來執行字符分類。 OpenCV的面部識別代碼的優秀資源是this website

我推薦你的另一個Python庫是「scikits.learn」。將cvArrays發送到scikits非常容易。在數據上學習和運行機器學習算法。使用SVM的OCR的基本示例是here

使用流形學習進行手寫字符識別的另一個更復雜的示例是here