安卓工作室OpenCV 3.2,无法使用本地OpenCV打开视频文件或安卓相机

3

我目前正在进行与相机/视频相关的Android本地图像处理工作。

我正在使用OpenCV 3.2来捕获和处理图像。
问题在于我无法打开任何类型的视频源或相机

这是我的C++代码。

cv::VideoCapture cap;
cv::Mat frame;

JNIEXPORT void JNICALL
Java_com_project_vmtest_Native_openVideo(JNIEnv *env, jobject instance, jstring fileName) {

    const char * fileNameNative;
    jboolean isCopy;
    fileNameNative = env->GetStringUTFChars(fileName, &isCopy);

    cap = cv::VideoCapture(fileNameNative);
    cap.open(fileNameNative);
    if(cap.isOpened())        // ALWAYS FALSE HERE!!!!
        cap.read(frame);
}

JNIEXPORT void JNICALL
Java_com_project_vmtest_Native_render(JNIEnv *env, jclass type) {
    if(engine){
        cap.read(frame);
        if (frame.empty())      return;    // ALWAYS RETURNS HERE!!!!
        engine->prepare(frame);
        engine->renderObjToFBO();
        engine->renderFrame();
        engine->clearFrameData();
    }
}

我检查了fileName,看起来它是正确的。
也就是说,这是我的文件结构:

app\src\main\cpp\native_main.cpp    // native code
app\src\main\assets\vmData\test\testFile.mp4   // video file

那么fileName就是:

fileName = "../assets/vmData/test/testFile.mp4"

我尝试使用“..\assets\vmData\test\testFile.mp4”,但没有任何改变。

我尝试使用cap.open(CV_CAP_ANDROID + 0);来捕获相机预览,但是得到了同样的结果,VideoCapture根本不会打开!

我使用以下代码启用了Android相机权限。

<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>
<uses-feature android:name="android.hardware.camera.front"/>
<uses-feature android:name="android.hardware.camera.front.autofocus"/>

我的测试设备是Android 5.0 Lollypop,所以我不认为这是任何权限问题。

我已经苦苦挣扎了几个小时。
非常感谢您的帮助!


可能相关:https://github.com/headupinclouds/gatherer/issues/19(请参见最后一条记录)。更相关的是:https://github.com/opencv/opencv/issues/5374#issuecomment-141995879。 - Morrison Chang
@MorrisonChang 我查看了链接,但没有找到对我的情况有用的信息。不管怎样,感谢你的回复;) - Suhyeon Lee
2个回答

3

0

我在 Native 代码中无法打开相机,最终使用了 Android OpenCV 相机实现 opencv.android.CameraBridgeViewBase


MainActivity.java

public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2 {

    private CameraBridgeViewBase mCvCamView;
    Mat matInput, matOutput;

    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS:
                    mCvCamView.enableView();
                    break;
                default:
                    super.onManagerConnected(status);
                    break;
            }
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mCvCamView = (CameraBridgeViewBase)findViewById(R.id.cam_view);
        mCvCamView.setVisibility(SurfaceView.VISIBLE);
        mCvCamView.setCvCameraViewListener(this);
        mCvCamView.setCameraIndex(1); // front-camera(1),  back-camera(0)
        mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
    }

    @Override
    public void onPause()
    {
        super.onPause();
        if (mCvCamView != null)
            mCvCamView.disableView();
    }

    @Override
    public void onResume()
    {
        super.onResume();

        if (!OpenCVLoader.initDebug()) {
            Log.d(TAG, "onResume :: Internal OpenCV library not found.");
            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_2_0, this, mLoaderCallback);
        } else {
            Log.d(TAG, "onResume :: OpenCV library found inside package. Using it!");
            mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
        }
    }

    public void onDestroy() {
        super.onDestroy();
        if (mCvCamView != null)
            mCvCamView.disableView();
    }

    @Override
    public void onCameraViewStarted(int width, int height) {
        if ( matOutput == null || matOutput.empty() )
            matOutput = new Mat(height, width, CvType.CV_8UC4, new Scalar(255, 0, 0, 255));
    }

    @Override
    public void onCameraViewStopped() {}

    @Override
    public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
        matInput = inputFrame.rgba();
        Native.extract(matInput.getNativeObjAddr(), matOutput.getNativeObjAddr());
        return matOutput;
    }

}


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <org.opencv.android.JavaCameraView
        android:id="@+id/cam_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接