最近在做研究時,常常需要把圖像中的數據紀錄下來。例如像下邊這張圖,需要手動把每一個標籤上的面積記錄到Excel中。同樣的圖有十幾張,一張圖有50到150個標籤。以人工一筆一筆紀錄,費時費勁又容易出錯,不如寫個程式讓電腦來辨識文字。
以程式辨識印刷字體這項技術有個專有名稱叫做「光學字元辨識 (OCR, Optical Character Recognition)」,在資訊工程裡已被研究多年,現今已經發展成熟。目前OCR技術以開源專案Tesseract OCR最流行,Python可以透過PyTesseract來使用,C#的emguCV把TesseractOCR包裝進去可以直接使用,Matlab則是把它放入Computer vision toolbox裡面,只要下載好toolbox就能用了。
由於使用OCR時需要像機器學習一樣,給OCR引擎餵訓練集,並且人工修正訓練資料。因此前期開發需要大量人力。過去我曾使用過C#的emguCV,搭配jTessBoxEdtor來訓練OCR引擎。但使用上較不方便,需要花上大量時間與精力才能完成訓練。Matlab提供了一個簡單的界面讓我們可以快速修正資料,因此在使用過後我個人認為是最輕鬆的。下面就來介紹整體的使用方法。
在Matlab裡找到Home → Add-Ons → Get Add-Ons,打開Add-Ons Explorer
搜尋"Computer vision toolbox",在頁面中點擊Install即可。(我已經安裝了,所以Install按鈕換成Open documentation和Manage了)
在做影像處理(Image Processing)時,都要先對影像做預處理(Preprocessing),把雜訊去除以得到更佳的結果。在做OCR時以不例外,我們需要先將影像裡文字的部分擷取出來,之後電腦辨識效果才會好。
我針對上圖把白底的文字標籤擷取出來,並把每個標籤另存成新的圖檔。代碼如下:
files = dir('*.jpg'); %取得所有圖檔
i = 1; %圖像流水號
for file = files'
im = imread(file.name);
gray = rgb2gray(im); %轉灰階
thres = 200;
bw = gray > thres; %二值化,閾值需調整
bwfill = imfill(bw,'holes'); %填滿內部孔洞
minArea = 4000;
bwfill = bwareaopen(bwfill,minArea); %刪去雜訊,閾值需調整
props = regionprops(bwfill); %計算各區域性質
for prop = props'
cropped = imcrop(im, prop.BoundingBox); %擷取文字框
imwrite(cropped,"Labels\\label-" + i + ".jpg"); %另存圖檔
i = i + 1;
end
end
其中以灰階後顏色數據 > 200 作為判斷文字框的依據,這點需要針對不同狀況做修改。另外我還用bwareaopen()
把一些小雜訊去除,這點也是需要根據圖像品質來調整。
擷取好的文字影像就像這樣: