You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android平台OpenCV相机预览异常问题求助

Fixing OpenCV Camera Preview Issues on Android

Hey there, let's troubleshoot your OpenCV camera preview problem together. Looking at your error logs and code, there are several key issues causing the preview to fail. Let's break them down one by one:

1. Resolve OpenCV Library Loading Error (Cannot load info library for OpenCV)

This error usually stems from incorrect OpenCV integration or initialization:

  • Check OpenCV Native Library Integration: Ensure you've properly linked the OpenCV native libraries in your project. If you're using a local OpenCV SDK, add this to your app-level build.gradle:
    sourceSets {
        main {
            jniLibs.srcDirs += ['path/to/OpenCV-android-sdk/sdk/native/libs']
        }
    }
    
  • Fix BaseLoaderCallback Context: Your callback uses mAppContext which isn't initialized. Replace it with MainActivity.this or getApplicationContext() to avoid null reference issues.
  • Correct OpenCV Initialization: initDebug() is only intended for debug builds. For better compatibility across devices, use OpenCVLoader.initAsync() instead of initDebug() in your onResume method.

2. Fix Critical Logic Errors in MainActivity

Your code has a few bugs that directly break the camera preview functionality:

  • Remove Wrong super.onPause() in onResume: This line pauses your Activity immediately when resuming, which kills the camera preview before it even starts. Delete this line entirely.
  • Handle Permission Grant Callback: Your permission() method requests camera permissions but doesn't handle the result. Add this override to re-initialize the camera once permissions are granted:
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 50) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Initialize camera after permission is approved
                initCameraView();
                // Re-initialize OpenCV
                if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_4_0, this, baseLoaderCallback)) {
                    Toast.makeText(this, "Failed to initialize OpenCV", Toast.LENGTH_SHORT).show();
                }
            } else {
                Toast.makeText(this, "Camera permission is required to use this feature", Toast.LENGTH_SHORT).show();
            }
        }
    }
    
  • Avoid Null cameraBridgeViewBase: Currently, if permissions aren't granted on first launch, cameraBridgeViewBase remains null. The above callback fixes this by initializing it only after permission approval.

3. Address Camera Property Access Warnings

The errors like Access denied finding property "vendor.camera.aux.packagelist" are mostly harmless for non-system apps, but you can improve compatibility by:

  • Switch to JavaCameraView: JavaCamera2View has stricter device requirements. Try replacing it in your layout with the more compatible JavaCameraView:
    <org.opencv.android.JavaCameraView
        android:id="@+id/myCameraView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:show_fps="true"/>
    
  • Add Camera Permissions to AndroidManifest.xml: Ensure you have these entries (even if you request runtime permissions):
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-feature android:name="android.hardware.camera"/>
    <uses-feature android:name="android.hardware.camera.autofocus"/>
    

Final Modified MainActivity Snippet

Here's the cleaned-up version of your activity with all fixes applied:

public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2 {
    CameraBridgeViewBase cameraBridgeViewBase;
    Mat mat1, mat2, mat3;
    BaseLoaderCallback baseLoaderCallback;

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

    @Override
    public void onCameraViewStarted(int width, int height) {
        mat1 = new Mat(width, height, CvType.CV_8UC4);
        mat2 = new Mat(width, height, CvType.CV_8UC4);
        mat3 = new Mat(width, height, CvType.CV_8UC4);
    }

    @Override
    public void onCameraViewStopped() {
        mat1.release();
        mat2.release();
        mat3.release();
    }

    @Override
    public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
        mat1 = inputFrame.rgba();
        return mat1;
    }

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

    @Override
    protected void onResume() {
        super.onResume();
        if (cameraBridgeViewBase != null) {
            if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_4_0, this, baseLoaderCallback)) {
                Toast.makeText(this, "Failed to initialize OpenCV", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (cameraBridgeViewBase != null) {
            cameraBridgeViewBase.disableView();
        }
    }

    private boolean permission() {
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 50);
            return false;
        } else {
            initCameraView();
            return true;
        }
    }

    private void initCameraView() {
        cameraBridgeViewBase = findViewById(R.id.myCameraView);
        cameraBridgeViewBase.setVisibility(SurfaceView.VISIBLE);
        cameraBridgeViewBase.setCvCameraViewListener(this);
        baseLoaderCallback = new BaseLoaderCallback(MainActivity.this) {
            @Override
            public void onManagerConnected(int status) {
                switch (status) {
                    case BaseLoaderCallback.SUCCESS:
                        cameraBridgeViewBase.enableView();
                        Toast.makeText(MainActivity.this, "Success", Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        super.onManagerConnected(status);
                        Toast.makeText(MainActivity.this, "Failure", Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        };
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 50) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                initCameraView();
                if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_4_0, this, baseLoaderCallback)) {
                    Toast.makeText(this, "Failed to initialize OpenCV", Toast.LENGTH_SHORT).show();
                }
            } else {
                Toast.makeText(this, "Camera permission is required", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

Try these fixes step by step, and remember to sync your gradle files and clean/rebuild the project after making changes. Your camera preview should start working once these issues are resolved.

内容的提问来源于stack exchange,提问作者J.Doe

火山引擎 最新活动