Почему matchtemplate работает некорректно?

178
17 сентября 2019, 22:50

Есть задача: получить изображение с камеры, выделить нужный объект для слежения и следить за ним.

Использую OpenCV и метод matchtemplate(). Моя реализация:

  1. Получаю изображение с камеры
  2. В onPreviewFrame() обрабатываю байтовский массив, перевожу его в Mat объект.
  3. Делаю копию объекта, обрезаю ее по выделенной области.
  4. Создаю новый объект для хранения результата, вызываю matchtemplate().

Но, к сожалению, почему-то он не находит нужное изображение (например, белая точка на черном фоне, он указывает в какое-то другое место). Помогите разобраться.

public void onPreviewFrame(byte[] data, Camera camera) {
        mainActivity = new MainActivity();
        Log.d(TAG,"OnPreviewFRAME_START");
        Camera.Parameters parameters = camera.getParameters();
        int width = parameters.getPreviewSize().width;
        int height = parameters.getPreviewSize().height;
        // YUV -> Bitmap
        YuvImage yuv = new YuvImage(data, parameters.getPreviewFormat(), width, height, null);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        yuv.compressToJpeg(new Rect(0, 0, width, height), 100, out);
        Bitmap bmp = BitmapFactory.decodeByteArray(out.toByteArray(), 0, out.size());
        // Bitmap -> Mat
        Mat fImage = new Mat();
        bmp = bmp.copy(Bitmap.Config.ARGB_8888, true);
        Utils.bitmapToMat(bmp, fImage);
        Imgproc.cvtColor(fImage, fImage, Imgproc.COLOR_BGR2GRAY);
        // Crop image for template
        Mat crop_fImage = mainActivity.cropImage(fImage);
        Mat result = new Mat();
        Imgproc.matchTemplate(fImage, crop_fImage, result, Imgproc.TM_CCOEFF);
        Core.MinMaxLocResult r = Core.minMaxLoc(result);
        Log.d(TAG, "r.minLoc: " + String.valueOf(r.minLoc) + "  " + "r.maxLoc: " + String.valueOf(r.maxLoc));
        Mat result2 = new Mat();
        Imgproc.matchTemplate(fImage, crop_fImage, result2, Imgproc.TM_CCOEFF_NORMED);
        Core.MinMaxLocResult r2 = Core.minMaxLoc(result2);
        Log.d(TAG, "r2.minLoc: " + String.valueOf(r2.minLoc) + "  " + "r2.maxLoc: " + String.valueOf(r2.maxLoc));
        // Draw react around
        xPoint_1 = (int) r.minLoc.x;
        yPoint_1 = (int) r.minLoc.y;
        xPoint_2 = (int) r.maxLoc.x;
        xPoint_2 = (int) r.maxLoc.y;
        scanSpace = false;
        camera.setPreviewCallback(this);
}

Есть подозрение в том, что моя камера имеет высокое разрешение 1920х1080 (landscape), а само приложение работает в portrait режиме. Может что-то с этим связано + координаты сбиваются как-то, ну это мои догадки.

Суть в том, что новый прямоугольник не рисуется поверх старого, а отображается в другом месте.

READ ALSO
PlaceAutocomplete с gps кнопкой

PlaceAutocomplete с gps кнопкой

Я установил себе в приложение PlaceAutocomplete и получаю с него latitude и longitudeВсе работает отлично

140
Проблема связи клиента и сервера через сокет

Проблема связи клиента и сервера через сокет

Даже не знаю как корректно описать проблемуВообщем сделал класс Commander, который использует и сервер, и клиент

156
Java класс для Bluetooth Android

Java класс для Bluetooth Android

Всем приветВот пишу отдельный класс java, который будет отвечать чисто только за управление Bluetooth на android-устройстве

135
Корректны ли в Java записи подобного вида?

Корректны ли в Java записи подобного вида?

Приложение работает, но принято ли так писать в Java? Просто для каждой переменной неудобно писать "public static String

143