Red*_*ant 8 java android opencv computer-vision background-subtraction
我正在开发一个机器人项目,使用Android手机作为主处理器和相机来检测运动.我从OpenCV获得了Android二进制包并正确安装.我可以使用OpenCV原生相机捕捉图像并将其显示在屏幕上.但是我在使用背景减法类时遇到了问题.我可以在构造函数中创建一个新的BackgroundSubtractorMOG对象,但是当我尝试运行下面的代码时,它强制退出我从本机代码中得到错误"BackgroundSubtractorMOG中仅支持1-和3通道8位图像".我尝试将Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA更改为Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGB,然后它不强制退出,但我得到的只是一个黑屏.我很确定使用FRAME_RGB,bmp仍然为null,因为屏幕保持黑色,并且我在位图之后绘制的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 Code Online (Sandbox Code Playgroud)
我的SurfaceView的run()函数:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
run()中引用的processFrame()函数:
protected void processFrame(VideoCapture capture) {
capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
mBGSub.apply(mRgba, mFGMask);
}
Run Code Online (Sandbox Code Playgroud)
编辑:
最终工作的解决方案:
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);
}
Run Code Online (Sandbox Code Playgroud)
您是否尝试过将cvtColor与CV_RGB2RGBA和 一起使用CV_RGBA2RGB?因此,也许可以尝试将帧 RGBA 转换为 RGB,然后进行背景减法。像这样的东西:
protected void processFrame(VideoCapture capture) {
capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
Mat rgb;
Imgproc.cvtColor(mRgba, rgb, Imgproc.COLOR_RGBA2RGB);
mBGSub.apply(rgb, mFGMask);
}
Run Code Online (Sandbox Code Playgroud)
编辑:BackgroundSubtractorMOG您可以查看位于此处的 OpenCV 单元测试。然而,测试已经fail("Not yet implemented");在主测试用例中进行了。
我不确定这是否意味着测试未完成,或者支持BackgroundSubtractorMOG尚未实现。您可以尝试运行此单元测试中包含的代码,看看它是否确实有效。
另外,C++ 示例segment_objects.cpp作为使用示例可能会有所帮助。
希望有帮助!:)