web-dev-qa-db-ja.com

openCVを使用して画像から数字と文字を読み取る

C++でopencvを使用して画像から文字と数字を読み取るアプリケーションを開発しています。最初に、指定されたカラーイメージとカラーテンプレートをバイナリイメージに変更し、次にメソッドcvMatchTemplate()を呼び出しました。この方法は、テンプレートが一致する領域を強調表示しただけです。ただし、明確ではありません。領域を表示したくないだけです。画像の文字(文字と数字)を解析する必要があります。私はopenCVを初めて使用します。誰かが結果を得るための他の方法を知っていますか?

alt text

画像はカメラから取得されます。サンプル画像は上に表示されています。 LEDディスプレイ(130およびDelft Tanthaf)からすべてのテキストを取得する必要があります。

顔検出のサンプルアプリで試してみました顔を検出してくれます。 HaarCascadeファイルはopenCVで提供されます。そのファイルをロードして、メソッドcvHaarDetectObjects();を呼び出しました。文字を検出するために、openCVが提供するアプリケーションletter_recog.cppを使用してxmlファイルを作成しました。しかし、このファイルをロードすると、いくつかのエラーが表示されます(OpenCVエラー:未指定エラー>不明な関数で、ファイル........\ocv\opencv\src\cxcore\cxpersistence.cpp、line 4720)。私はこのエラーをウェブで検索し、使用されたlibファイルに関する情報を得ました。私はそうしましたが、エラーはまだ残っています。私のxmlファイルにエラーがありますか、それともこのxmlファイルをロードするメソッドを呼び出していますか((CvHaarClassifierCascade *)cvLoad( "builded xml file name"、0,0,0);)??助けてください...

前もって感謝します

21
asifkt

OpenCV 3.0(アクティブな開発)では、組み込みの「シーンテキスト」オブジェクト検出モジュールを使用できます〜

テキスト検出は、次の2つの論文に基づいています。

シーン内のテキストの場所を見つけたら、それらのスライスに対してあらゆる種類の標準OCRを実行できます(Tesseract OCRが一般的です)。そして、OpenCVのTesseractへの新しいインターフェースを使用したopencvにエンドツーエンドのサンプルがあります:

17
Kaolin Fire

照明の不一致、方向の変更、スケールの変更などのため、テンプレートマッチングはこの種のアプリケーションに対して堅牢ではない傾向があります。この問題を解決する一般的な方法は、機械学習を導入することです。独自のブースティング分類器をトレーニングすることによって実行しようとしていることは、1つの可能なアプローチです。しかし、あなたは正しく訓練をしているとは思いません。ポジティブトレーニング画像としてロゴを1つ、ロゴを含まない他の画像をネガティブな例として5つ提供したとおっしゃっていましたが、通常、トレーニングサンプルは数百または数千以上のオーダーである必要があります。 6つのトレーニングサンプルでトレーニングすることはできません。

機械学習に慣れていない場合は、ここに大まかに何をすべきかを示します。

1)検出しようとしているオブジェクトの多くのポジティブトレーニングサンプルを収集する必要があります(数百からですが、一般的にはより多くの陽気)。画像内の個々の文字を検出しようとしている場合は、個々の文字のトリミングされた画像を取得します。このために、MNISTデータベースから始めることができます。さらに、特定の問題について分類子をトレーニングするには、写真からバス上のキャラクターの多くのトリミングされた画像を取得します。長方形のLEDボードパネル全体を検出しようとしている場合は、それらの画像をポジティブトレーニングサンプルとして使用します。

2)多くの負のトレーニングサンプルを収集する必要があります。その数は、ポジティブトレーニングサンプルの数と同じ順序である必要があります。これらは、検出器を実行する画像に表示される他のオブジェクトの画像である可能性があります。たとえば、バスの正面、路面、道路沿いの木々などの画像をトリミングして、ネガティブな例として使用できます。これは、検出器を実行する画像内のこれらのオブジェクトを分類子が除外できるようにするためです。したがって、否定的な例は検出したくないオブジェクトを含む画像だけではありません。それらは、検出器を実行した画像で検出しようとしているオブジェクトと間違われる可能性のあるオブジェクトである必要があります(少なくともあなたの場合は)。

分類子のカスケードをトレーニングしてXMLモデルファイルを生成する方法については、次のリンクを参照してください。 http://note.sonots.com/SciSoftware/haartraining.html

バス上のLEDパネル全体ではなく、個々の文字のみを検出したいとおっしゃいましたが、最初にLEDパネルを検出して、対象の文字を含む領域を特定することをお勧めします。その後、この小さな領域内でテンプレートマッチングを実行するか、スライディングウィンドウアプローチを使用して、場合によっては複数のスケールで取得したこの領域のピクセルのパッチで個々の文字を認識するようにトレーニングされた分類子を実行します。 (注:上記のhaarcascadeブースティング分類器は文字を検出しますが、特定の文字を検出するようにトレーニングしない限り、検出された文字はわかりません...)この領域の文字をスライディングウィンドウ方式で検出すると、あなたは文字を表示する順序をあなたがそれらを単語などにつなげることができるようにします.

お役に立てれば。

編集:

@KaolinFireが言及したOpenCV 3のシーンテキストモジュールを個別に発見した後、偶然この古い投稿を偶然目にしました。

好奇心が強い人にとって、これはOPによって与えられたサンプル画像でその検出器を実行した結果です。検出器は複数の境界ボックスを返しますが、テキスト領域をローカライズできることに注意してください。

Result of OpenCV 3 text detector.

このメソッドは絶対確実ではないことに注意してください(少なくともデフォルトのパラメーターを使用したOpenCVのこの実装)。特に入力画像に多くの「ディストラクタ」が含まれている場合は、誤検知が発生する傾向があります。 GoogleストリートビューデータセットでこのOpenCV 3テキスト検出器を使用して取得したその他の例を次に示します。

Negative result 1Negative result 2Negative result 3Negative result 4

平行線(窓、壁など)の間に「テキスト」を見つける傾向があることに注意してください。 OPの入力画像には屋外のシーンが含まれている可能性が高いため、特に関心のある領域をLED標識の周りの小さな領域に制限しない場合、これは問題になります。

テキストのみ(たとえば、OPのサンプル画像のLED標識のみ)を含む「ラフ」領域をローカライズできる場合、このアルゴリズムを実行すると、境界ボックスをより緊密にすることができます。ただし、誤検出に対処する必要があります(おそらく、小さな領域を破棄するか、LED看板に文字が表示される方法に関する知識に基づくヒューリスティックを使用して、重複する境界ボックスから選択します)。

テキスト検出に関するその他のリソース(ディスカッション+コード+データセット)を以下に示します。

コード

データセット

GoogleストリートビューとMSRAデータセットはこちらにあります。これらのデータセットの画像は、バスのLED標識の画像と完全に同じではありませんが、いくつかの競合するアルゴリズムから「最良の」アルゴリズムを選択するか、機械学習アルゴリズムを最初からトレーニングするのに役立ちます。

http://www.iapr-tc11.org/mediawiki/index.php/Datasets_List

10
lightalchemist

記録された監視カメラビデオから時間を読み取る方法への私の回答を参照してください。 これを行うには、cvMatchTemplate()を使用できます/使用する必要があります。

5
Adi Shavit

固定バス宛先のセットを使用している場合は、テンプレートマッチングで十分です。

ただし、システムをより柔軟にしたい場合は、個々の文字ごとに何らかの形の輪郭/形状分析が必要になると思います。

1
kylestephens

EAST:Efficient Scene Text Detector- https://www.learnopencv.com/deep-learning-based-text-detection-using-opencv-c-python/ このリンクの下もご覧ください。 、C++とPythonの例があります。このコードを使用して、バスの数を検出しました(特定のオブジェクトがバスであることを検出した後)。

0
Artur