tl; dr My KNearestのトレーニングデータと実際のデータの次元が一致せず、アプリがクラッシュする可能性があります。私は私のトレーニングデータ(drawableリソース=>ビットマップ=> opencv行列)をインスタンス化する方法の私のpreProces
の方法が失敗の理由であると思われる。あなたの誰かが解決策を知っていますか?OpenCV Android行列を正規化する方法は?
私はAndroid用のOpenCVを使った簡単なOCRアプリのデモを手に入れようとしています。 KNearestのビルドを使用して文字を認識します。 KNearestオブジェクトが何かを検出できるようになるには、それを訓練する必要があります。トレーニングのために、私はいくつかのキャラクターアウトラインを使用します。
訓練は意外にも訓練画像の推定値を検出することができると思われる。私はそれが他の画像でも(または、私のアプリをクラッシュさせないで)そうしたかったと思う。
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
メソッドが失敗したり、描画可能なリソースをビットマップとして読み込んだりして行列に変換することが失敗する理由があります。あなたの中に似たような問題があったかどうか、どうやって解決したのかを知りたい。
更新:ビットマップから作成された行列にはかなりのノイズがあるようです。これが問題なのでしょうか?それでは、どうすればノイズを除去できますか?