Android: Как лучше отследить объекты?

112
02 октября 2019, 17:50

Необходимо отследить перемещение одной белой точки на черном фоне. Использую OpenCV и класс CameraPreview на основе SurfaceView. Как лучше реализовать это?

Моя идея:

  1. Делаем тач по области, где точка, сохраняем координаты.
  2. В методе onPreviewFrame по вызову преобразуем byte -> Mat object.
  3. Делаем temp Mat object для сравнения, обрезаем его по прямоугольнику, используя координаты тача. Будем использовать эту матрицу для хранения шаблона.
  4. Вызвать метод matchtemplate()
  5. Получив точку, где наибольшее сравнение - нарисовать прямоугольник

И так для каждого кадра.

Несколько вопросов: Как лучше перевести byte в Mat? Какой формат необходим для создания объекта матрицы из байтовского массива? Какой формат лучше для использования match template?

И ещё одна моя проблемка: Разрешение моего дисплея 1920 (высота) 1080(ширина), а параметры камеры наоборот 1920 (ширина) 1080 (высота). На выходе я получаю массив data с перевернутым изображением. Как правильно перевернуть массив с байтами? Или лучше это сделать с Mat объектом?

Вот код, что имею на данный момент. Поиск по шаблону выполняется, но результаты не те, которые нужны.

public void onPreviewFrame(byte[] data, Camera camera) {
    if (scanSpace) {
        mainActivity = new MainActivity();
        Log.d(TAG,"OnPreviewFRAME_START");
        Camera.Parameters parameters = camera.getParameters();
        int width = parameters.getPreviewSize().width;
        int height = parameters.getPreviewSize().height;
        Log.d(TAG, "Camera parameters: width: " + String.valueOf(width) + " height: " + String.valueOf(height) );

        //convert the byte[] to Bitmap through YuvImage;
        //make sure the previewFormat is NV21 (I set it so somewhere before)
        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());
        Log.d(TAG, "Frame (picture) parameter: width: " + String.valueOf(bmp.getWidth()) + " height: " + String.valueOf(bmp.getHeight()));
        //convert Bitmap to Mat; note the bitmap config ARGB_8888 conversion that
        //allows you to use other image processing methods and still save at the end
        Log.d(TAG, "BMP size for search: HEIGHT:  " + String.valueOf(bmp.getHeight()) + " WIDTH: " + String.valueOf(bmp.getWidth()));
        Mat orig = new Mat(bmp.getHeight(), bmp.getWidth(),CvType.CV_8UC3);
        bmp = bmp.copy(Bitmap.Config.ARGB_8888, true);
        Utils.bitmapToMat(bmp, orig);
        Imgproc.cvtColor(orig, orig, Imgproc.COLOR_BGR2GRAY,4);
        Log.d(TAG, "Old RES: " + String.valueOf(orig.rows()) + " " + String.valueOf(orig.cols()));
        Mat rotMat = new Mat(2, 3, CvType.CV_32FC1);
        Mat destination = new Mat(orig.rows(), orig.cols(), orig.type());
        Point center = new Point(destination.cols() / 2, destination.rows() / 2);
        rotMat = Imgproc.getRotationMatrix2D(center, 90, 1);
        Imgproc.warpAffine(orig, destination, rotMat, destination.size());
        Log.d(TAG, "NEW RES: " + String.valueOf(destination.rows()) + " " + String.valueOf(destination.cols()));

        Mat crop_orig = mainActivity.cropImage(orig);
        Log.d(TAG, "CROP IMAGE PARAMS: HEIGHT:  " + String.valueOf(crop_orig.height()) + " WIDTH: " + String.valueOf(crop_orig.width()));
        Mat result = new Mat();
        matchTemplate(orig, crop_orig, result, Imgproc.TM_SQDIFF);
        Core.MinMaxLocResult r = Core.minMaxLoc(result);
        System.out.println(r.minVal + " " + r.minLoc);
        Core.MinMaxLocResult mmr = Core.minMaxLoc(result);
        Point matchLoc = mmr.maxLoc;
        double tmp_x = matchLoc.x;
        double tmp_y = matchLoc.y;
        xPoint_1 = (int) tmp_x;
        yPoint_1 = (int) tmp_y;
        Log.d(TAG, "FINISH template");
        scanSpace = false;
        camera.setPreviewCallback(this);
    }
}
READ ALSO
Не работает алгоритм A*

Не работает алгоритм A*

Метод получает на вход координаты начальной точки и конечной

137
Ошибка java.lang.RuntimeException:…невозможно запустить действие

Ошибка java.lang.RuntimeException:…невозможно запустить действие

Создаю приложение с ЯндексКартами

103
Запуск exe файла и передача значений Java

Запуск exe файла и передача значений Java

Всем привет, вообщем столкнулся с такой проблемой

113
Отступ между View-компонентами в ConstraintLayout

Отступ между View-компонентами в ConstraintLayout

Вопрос достаточно простой, правда сам пока не нашёл на него ответ

119