tl; dr Мои данные обучения и реальные данные KNearest не имеют одинаковых размеров и приводят к сбою моего приложения. Я подозреваю, что мой метод preProces
того, как я создаю свои данные обучения (drawable resource => bitmap => opencv matrix), является причиной сбоя. Кто-нибудь из вас знает решение?Как нормализовать матрицы OpenCV Android?
Я пытаюсь получить рабочую демонстрацию простого приложения OCR с OpenCV для Android. Я использую сборку в KNearest для распознавания символов. Прежде чем объект 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
ничего не делает больше, чем нормализации матрицы. Это то, что мой 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
, прежде чем передать его в метод mKNearest.findNeareset(...)
. Это происходит, когда происходит авария. Данные обучения и реальные данные, похоже, не имеют одинаковых размеров, что должен решить метод preProces
.
Мое предположение заключается в том, что либо мой метод preProces
терпит неудачу, либо загрузка загружаемых ресурсов в виде растрового изображения, а затем преобразование их в матрицы является причиной его отказа. Я хотел бы знать, были ли у некоторых из вас подобные проблемы и как вы это решили.
Обновление: Похоже, что в матрицах довольно много шума, который создается из растрового изображения. Может ли это быть проблемой, если да, то как удалить шум?