Вычитание фона в OpenCV Android

Я работаю над проектом робототехники, используя телефон Android в качестве основного процессора и камеру для обнаружения движения. Я получил бинарный пакет Android от OpenCV и правильно установил его. Я могу снимать изображения с помощью собственной камеры OpenCV и отображать их на экране. Однако у меня проблемы с использованием класса вычитания фона. Я могу создать новый объект BackgroundSubtractorMOG в конструкторе, но когда я пытаюсь запустить приведенный ниже код, он принудительно завершает работу. Я получаю сообщение об ошибке «В BackgroundSubtractorMOG поддерживаются только 1- и 3-канальные 8-битные изображения» из собственного кода. Я попытался изменить Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA на Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGB, а затем он не принудительно завершил работу, но все, что я получил, это черный экран. Я почти уверен, что bmp по-прежнему равен нулю с FRAME_RGB, потому что экран остается черным, а счетчик кадров в секунду, который я рисовал сразу после растрового изображения (удален из кода, опубликованного ниже для ясности и в качестве шага по устранению неполадок), не отображается.

Я взглянул на код OpenCV C ++ для этой функции (, строка 388 здесь ), и ошибка типа изображения возникает, если тип изображения не является CV_8UC1 или CV_8UC3, поэтому я попытался использовать java CvType.CV_8UC3 вместо Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA в захвате.retrieve (), но он принудительно закрывается, и я получил ошибку «Формат выходного кадра не поддерживается».

Я предполагаю, что у меня только что возникла проблема с преобразованием типов, но я не могу понять на всю жизнь, где типы изображений OpenCV, специфичные для Android, подходят к их обычным типам изображений, которые задокументированы. Любая помощь будет оценена.

Переменные:

private SurfaceHolder mHolder;
private VideoCapture mCamera;
private Mat mRgba;
private Mat mFGMask;
private BackgroundSubtractorMOG mBGSub;

Функция run () моего SurfaceView:

public void run() {    
    Bitmap bmp = null;

    synchronized (this) {
        if (mCamera == null)
            break;

        if (!mCamera.grab()) {
            Log.e(TAG, "mCamera.grab() failed");
            break;
        }

        processFrame(mCamera);
        bmp = Bitmap.createBitmap(mFGMask.cols(), mFGMask.rows(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(mFGMask, bmp);
    }

    if (bmp != null) {
        Canvas canvas = mHolder.lockCanvas();
        if (canvas != null) {
            canvas.drawBitmap(bmp, (canvas.getWidth() - bmp.getWidth()) / 2, (canvas.getHeight() - bmp.getHeight()) / 2, null);
            mHolder.unlockCanvasAndPost(canvas);
        }
        bmp.recycle();
    }
}

Функция processFrame (), на которую имеется ссылка в run ():

protected void processFrame(VideoCapture capture) {
    capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
    mBGSub.apply(mRgba, mFGMask);
}

Редактировать:

Решение, которое в итоге сработало:

protected void processFrame(VideoCapture capture) {
    capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGB);
    //GREY_FRAME also works and exhibits better performance
    //capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_GREY_FRAME);
    mBGSub.apply(mRgba, mFGMask, 0.1);
    Imgproc.cvtColor(mFGMask, mRgba, Imgproc.COLOR_GRAY2BGRA, 4);
}

8
задан Jav_Rock 31 May 2012 в 13:11
поделиться