2016-04-19 8 views
1

tl; dr My KNearestのトレーニングデータと実際のデータの次元が一致せず、アプリがクラッシュする可能性があります。私は私のトレーニングデータ(drawableリソース=>ビットマップ=> opencv行列)をインスタンス化する方法の私のpreProcesの方法が失敗の理由であると思われる。あなたの誰かが解決策を知っていますか?OpenCV Android行列を正規化する方法は?

私はAndroid用のOpenCVを使った簡単なOCRアプリのデモを手に入れようとしています。 KNearestのビルドを使用して文字を認識します。 KNearestオブジェクトが何かを検出できるようになるには、それを訓練する必要があります。トレーニングのために、私はいくつかのキャラクターアウトラインを使用します。

A black background with the outline of a 0これは1つ(ゼロ)です。

訓練は意外にも訓練画像の推定値を検出することができると思われる。私はそれが他の画像でも(または、私のアプリをクラッシュさせないで)そうしたかったと思う。

Map<Character, Integer> images = new HashMap<>(); 
images.put('0', R.drawable.training0); 

// Prepare two sets of data, the images and their values. 
Mat trainingImages = new Mat(); 
Mat trainingLabels = new Mat(); 
for (int i = 0; i < 50; i++) { 
    for (Map.Entry<Character, Integer> entry : images.entrySet()) { 
     Bitmap bitmapImage = BitmapFactory.decodeResource(
      this.getResources(), entry.getValue()); 
     Mat matImage = new Mat(); 
     Utils.bitmapToMat(bitmapImage, matImage); 

     trainingLabels.push_back(new MatOfInt(entry.getKey() - '0')); 
     trainingImages.push_back(
      preProces(
       matImage, new Rect(0, 0, matImage.width(), matImage.height()))); 
     } 
    } 

mKNearest.train(trainingImages, Ml.ROW_SAMPLE, trainingLabels); 

preProces方法は、行列を正規化するよりも何もしません:これは私がKNearestモデルを訓練するために何をしたかです。これは私のpreProces方法は次のようになります。私は(可能な)文字の周りに四角形を描画することができた、その難しいことではありませんでした(可能な)文字を見つけるために、画像をセグメント化

private Mat preProces(Mat image, Rect poi) { 
    Mat cutout = new Mat(image, poi); 
    Mat resized = new Mat(10, 10, CvType.CV_32F); 
    Mat converted = new Mat(); 
    Imgproc.resize(cutout, resized, resized.size()); 
    resized.reshape(1, 1).convertTo(converted, CvType.CV_32F); 
    return converted; 
} 

。それが完了したら、私はメソッドに渡す前に、私のpreProcesメソッドを通してすべての興味のあるポイントを渡します。これは、クラッシュが発生したときです。トレーニングデータと実際のデータは同じ次元を持つようには見えませんが、preProcesメソッドで解決する必要があります。

私の推測では、私のpreProcesメソッドが失敗したり、描画可能なリソースをビットマップとして読み込んだりして行列に変換することが失敗する理由があります。あなたの中に似たような問題があったかどうか、どうやって解決したのかを知りたい。

更新:ビットマップから作成された行列にはかなりのノイズがあるようです。これが問題なのでしょうか?それでは、どうすればノイズを除去できますか?

答えて

0

この質問に対する回答はかなりシンプルだったようです。私はImgproc.canny()を使って実際のデータのエッジを検出しましたが、トレーニングデータでは検出しませんでした。この問題は、トレーニングデータをImgproc.canny()に渡すと解決されました。

... 
Bitmap bitmapImage = BitmapFactory.decodeResource(
    this.getResources(), entry.getValue()); 
Mat matImage = new Mat(); 
Utils.bitmapToMat(bitmapImage, matImage); 

// This was all I had to add to the training data preparation. 
Mat cannyImage = new Mat(); 
Imgproc.Canny(matImage, cannyImage, 1.0, 255.0); 

trainingLabels.push_back(new MatOfInt(entry.getKey() - '0')); 
trainingImages.push_back(
    preProces(
     cannyImage, new Rect(0, 0, cannyImage.width(), cannyImage.height()))); 
} 
... 
関連する問題