Я работаю над робототехническим проектом с использованием телефона Android в качестве основного процессора и камеры для обнаружения движения.Я получил двоичный пакет Android от OpenCV и правильно установил его.Я могу захватывать изображения с помощью встроенной камеры OpenCV и отображать их на экране.У меня проблемы с использованием фона вычитания фона, хотя.Я могу создать новый объект BackgroundSubtractorMOG в конструкторе, но когда я пытаюсь запустить приведенный ниже код, он принудительно завершает работу, и я получаю сообщение об ошибке «Только 1- и 3-канальные 8-битные изображения поддерживаются в BackgroundSubtractorMOG» из собственного кода.Я попытался изменить Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA на Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGB, и затем он не принудительно завершается, но все, что я получаю, это черный экран.Я почти уверен, что bmp все еще равен нулю с FRAME_RGB, потому что экран остается черным, а счетчик fps, который я рисовал сразу после растрового изображения (удален из кода, приведенного ниже для ясности и как этап устранения неполадок), не отображается.
Я взглянул на код OpenCV C ++ для этой функции ( строка 388 здесь ), и возникает ошибка типа изображения, если тип изображения не CV_8UC1 или CV_8UC3, поэтому я попыталсяиспользование java CvType.CV_8UC3 вместо Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA в capture.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);
}