14

ナンバー プレート認識用のシンプルな PC アプリケーション (Java + OpenCV + Tess4j) を開発しようとしています。画像はあまり良くありません (さらに良くなるでしょう)。tesseract の画像を前処理したいのですが、ナンバー プレートの検出 (長方形の検出) に行き詰まっています。

私の手順:

1) ソース画像

真のイメージ

Mat img = new Mat();
img = Imgcodecs.imread("sample_photo.jpg"); 
Imgcodecs.imwrite("preprocess/True_Image.png", img);

2) グレースケール

Mat imgGray = new Mat();
Imgproc.cvtColor(img, imgGray, Imgproc.COLOR_BGR2GRAY);
Imgcodecs.imwrite("preprocess/Gray.png", imgGray);

3) ガウスぼかし

Mat imgGaussianBlur = new Mat(); 
Imgproc.GaussianBlur(imgGray,imgGaussianBlur,new Size(3, 3),0);
Imgcodecs.imwrite("preprocess/gaussian_blur.png", imgGaussianBlur);  

4) 適応閾値

Mat imgAdaptiveThreshold = new Mat();
Imgproc.adaptiveThreshold(imgGaussianBlur, imgAdaptiveThreshold, 255, CV_ADAPTIVE_THRESH_MEAN_C ,CV_THRESH_BINARY, 99, 4);
Imgcodecs.imwrite("preprocess/adaptive_threshold.png", imgAdaptiveThreshold);

これは、プレート領域の検出である(おそらく今のところデスキューなしでも)5番目のステップです。

ペイントを使用して (4 番目のステップの後) 画像から必要な領域を切り取り、次のように取得しました。

プレート領域

次に、OCRを行いました(tesseract、tess4j経由):

File imageFile = new File("preprocess/adaptive_threshold_AFTER_PAINT.png");
ITesseract instance = new Tesseract();
instance.setLanguage("eng");
instance.setTessVariable("tessedit_char_whitelist", "acekopxyABCEHKMOPTXY0123456789");
String result = instance.doOCR(imageFile); 
System.out.println(result);

そして得られた(十分?)結果 - "Y841ox EH"(ほぼ真)

4 番目のステップの後にプレート領域を検出してトリミングするにはどうすればよいですか? 1 ~ 4 ステップで変更 (改善) を行う必要がありますか? Java + OpenCV (JavaCV ではない) を介して実装された例を見たいと思います。
前もって感謝します。

編集(@Abdul Fatirの回答に感謝)まあ、この質問に興味のある人のために、(少なくとも私にとっては)動作するコードサンプル(Netbeans + Java + OpenCV + Tess4j)を提供します。コードは最高ではありませんが、勉強のためだけに作成しました。
http://pastebin.com/H46wuXWn ( tessdataフォルダーをプロジェクト フォルダーに入れることを忘れないでください)

4

3 に答える 3

13

このタスクを実行する方法をお勧めします。

  1. グレースケールに変換します。
  2. 3x3 または 5x5 フィルターを使用したガウスぼかし。
  3. ソーベル フィルターを適用して、垂直方向のエッジを見つけます。

    Sobel(gray, dst, -1, 1, 0)

  4. 結果のイメージをしきい値処理して、バイナリ イメージを取得します。
  5. 適切な構造化要素を使用してモルフォロジー クローズ操作を適用します。
  6. 結果の画像の輪郭を見つけます。
  7. minAreaRect各輪郭を検索します。縦横比と最小および最大面積に基づいて長方形を選択します。
  8. 選択した輪郭ごとに、エッジ密度を見つけます。エッジ密度のしきい値を設定し、そのしきい値に違反する長方形を可能なプレート領域として選択します。
  9. この後、いくつかの長方形が残ります。方向または適切と思われる基準に基づいてそれらをフィルタリングできます。
  10. 検出されたこれらの長方形部分を画像からadaptiveThreshold切り取り、OCR を適用します。

a)ステップ 5 の結果

手順 5 の結果

b)ステップ 7 の後の結果。緑色のものはすべてminAreaRects であり、赤色のものは次の基準を満たすものです: アスペクト比範囲 (2,12) & 面積範囲 (300,10000)

c)ステップ 9 の後の結果。選択された長方形。基準: エッジ密度 > 0.5

ここに画像の説明を入力

編集

エッジ密度については、上記の例で行ったことは次のとおりです。

  1. Canny Edge 検出器を入力画像に直接適用します。cannyED 画像をIcとします。
  2. ソーベル フィルターとIcの結果を乗算します。基本的に、Sobel と Canny の画像の AND を取ります。
  3. Gaussian 大きなフィルターで結果の画像をぼかします。私は21x21を使用しました。
  4. OTSU の方法を使用して、結果の画像をしきい値処理します。バイナリイメージが得られます
  5. 赤い四角形ごとに、この四角形の内側の部分 (バイナリ イメージ内) を回転させて直立させます。四角形のピクセルをループし、白いピクセルをカウントします。(どうやって回すの?

エッジ密度 = 長方形内の白いピクセルの数/総数 長方形内のピクセル数

  1. エッジ密度のしきい値を選択します。

: 手順 1 ~ 3 を実行する代わりに、手順 5 のバイナリ イメージを使用してエッジ密度を計算することもできます。

于 2016-05-19T08:58:43.720 に答える