2016年8月21日 星期日

Microsoft Cognitive Services (2) - 使用Vision API進行OCR

既然是Vision,那範圍當然不只包含辨識圖片,或是找到照片中的人臉,Vision API還可以幫你達成OCR的功能。實際測試的結果,如果是印刷體的文字,辨識率算是不錯了,而且支援多種語文,包含中文,就很值得大家關注一下了。

底下是實際辨識一張slide的結果,你會發現不管是標題或是內文,辨識度都非常好(不過也是因為是標準清晰的印刷體的原因):

別小看Vision API的OCR功能,在同一個圖檔中,有多行不同角度傾斜的文字,在一定的範圍內,Vision API依舊可以辨識出來,它是一個區塊一個區塊去辨識的,重點是,程式寫起來一點都不複雜。

底下這段WPF的Code,就是按下上圖中的『選擇文字照片』之後,所執行的完整程式碼:

//抓取key
var VisionApiKey = textBoxkey.Text.Trim();
//讀取圖檔
var openDlg = new Microsoft.Win32.OpenFileDialog();
//圖檔過濾類型
openDlg.Filter = "JPEG Image(*.jpg)|*.jpg|*.png|*.png";
bool? result = openDlg.ShowDialog(this);
//沒選檔案
if (!(bool)result)   return;

//取得選擇的檔案名稱
string filePath = openDlg.FileName;
//OCR OcrResults
OcrResults OcrResults;
//建立VisionServiceClient
var visionClient = new Microsoft.ProjectOxford.Vision.VisionServiceClient(VisionApiKey); 
using (var fs = new FileStream(filePath, FileMode.Open))
{
    this.textBox.Text = "辨識中...";
    //以繁體中文辨識
    OcrResults = await visionClient.RecognizeTextAsync(fs, LanguageCodes.ChineseTraditional);
    this.textBox.Text = "";
}

this.textBox.Text = "";
//抓取每一區塊的辨識結果
foreach (var Region in OcrResults.Regions)
{
    //抓取每一行
    foreach (var line in Region.Lines)
    {
        //抓取每一個字
        foreach (var Word in line.Words)
        {
            //顯示辨識結果
            this.textBox.Text += Word.Text;
        }
        //加換行
        this.textBox.Text += "\n";
    }
}

//顯示原始圖片
Uri fileUri = new Uri(filePath);
BitmapImage bitmapSource = new BitmapImage();
bitmapSource.BeginInit();
bitmapSource.CacheOption = BitmapCacheOption.None;
bitmapSource.UriSource = fileUri;
bitmapSource.EndInit();
image1.Source = bitmapSource;

幾乎不用解釋,非常的簡單。

建立了VisionServiceClient之後,將讀入的stream傳遞給RecognizeTextAsync方法,並且指定要用繁體中文辨識。

結果以OcrResults這個類別的物件回傳,其中OcrResults.Regions是辨識出的每一個文字區塊,接著以Region.Lines和line.Words抓取到每一行和每一個字,就這樣,辨識出來囉…

超容易的吧!

沒有留言: