2017年10月19日木曜日

tesseract-ocrとC#で7セグを読み取ってみる

OCRで検索するとよく見かけるのが本題のtesseract-ocrでしたのでこちらを使ってみました。

C#で使ってみたかったのでNuGetで導入してみます。
"Tesseract"で検索するといくつか見つかるのですが、Charles Weldさんのパッケージがよく使われているようです(文言は若干異なるようですが...)

言語データは別途ダウンロード & 配置するのですが、今回は7セグ用の学習データを使わせてもらいます。
https://github.com/arturaugusto/display_ocr
こちらをダウンロードします。
学習データのフォルダ構成の中で、以下が学習データっぽく、この階層のファイルを指定すれば良さそうですが...
display_ocr-master\letsgodigital\letsgodigital.traineddata

他の言語などを見ると言語(上記で言うと"letsgodigital"の下に"tessdata"の下に上記ファイルが配置されているようですので、"tessdata"というフォルダを掘ってその下に上記階層のファイルを配置しました(この辺のしきたりはよく解っていません)。
また、VisualStudioのprojectフォルダはパスにspaceが入っていたりするので、ユーザーフォルダに配置しています(なるべくトラブらないようにしているだけで実は問題ないかもしれません)。

ということで学習データのパスは以下としています。
C:\Users\hoge\Documents\tmp\display_ocr-master\letsgodigital\tessdata

コードは以下ですが文字によっては認識してくれるようです。
サンプル画像はgoogleの画像検索で7セグの画像を探してきたのですが...
- 白地に黒文字
- セグメントがつながっている方が認識しやすかった(学習データの中の画像はseg毎に分離しているのでつながっていない画像で学習していると思うのですが...)
- 文字が画像の端まであると認識してくれない (要余白?)
という感じで、誤認識やそもそも読めない場合もあるようです。
(文字列の部分に\nだけ表示されたりするようです...以下のコードで読める画像もあればNGなのもあるようです)

コードは以下で動かしてみました。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tesseract;                // 追加
using System.Diagnostics;

namespace tesseract01
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // 解析したい画像のファイルパス
            var imgPath = @"C:\Users\hoge\Documents\tmp\7seg8.png";

            // jpn.traineddata等の学習データが格納されたディレクトリパス
            var dataDirPath = @"C:\Users\hoge\Documents\tmp\display_ocr-master\letsgodigital";

            // 使用する学習データの言語(ディレクトリパスに格納されている言語に限る)
            var lang = "letsgodigital";

            if (!System.IO.File.Exists(imgPath))
            {
                Console.Error.WriteLine("画像のパスに画像が見つかりませんでした");
                return;
            }

            string traindedDataPath = System.IO.Path.Combine(dataDirPath, "tessdata", lang + ".traineddata");
            if (!System.IO.File.Exists(traindedDataPath))
            {
                Console.Error.WriteLine(lang + ".traineddataがみつかりませんでした");
                return;
            }

            using (var image = new System.Drawing.Bitmap(imgPath))
            {
                try {
                    using (var engine = new Tesseract.TesseractEngine(dataDirPath, lang))
                    {
                        engine.DefaultPageSegMode = PageSegMode.SingleLine;
                        using (var page = engine.Process(image))
                        {
                            var resultText = page.GetText();
                            Console.Write(resultText);
                        }
                    }
                } catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }
            }
        }
    }
}

参考にさせていただきましたページ
http://whoopsidaisies.hatenablog.com/entry/2013/12/16/174819
http://blog.nomulabo.com/article/422712502.html
http://blog.ch3cooh.jp/entry/20140718/1405643400

1 件のコメント: