OpenCV JavaCameraView显示黑屏/黑屏

时间:2020-05-09 01:53:43

标签: android opencv

第一次成为Android开发人员,过去几个月来,我一直在努力使用OpenCV的JavaCameraView,它始终显示黑屏/黑屏。我在线上关注了很多教程,但是将它们放到发球台上却带来了0条结果。我知道我的代码正确地加载了OpenCV,而Logcat描述了该代码尝试启动相机视图,但无济于事。我需要帮助。代码中有问题的部分是:

registerForContextMenu(myRecyclerView);

我的activity_main XML文件是这样的:

public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2 {
//Activate Camera
private BaseLoaderCallback baseLoaderCallback = new BaseLoaderCallback (this) {
    @Override
    public void onManagerConnected(int status) {
        if (status == BaseLoaderCallback.SUCCESS) {
            OpenCVCamView.enableView();                                //Enable Cam View
            Log.d(TAG, "Tried enabling Camera View!");
        } else { super.onManagerConnected(status); }
    }
};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.d(TAG, "on Create");
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    setContentView(R.layout.activity_main);                                     //UI Layout loaded
    OpenCVCamView = findViewById(R.id.cam_view);                                    
    textView = findViewById(R.id.arduino_log);                                  
    textView.setVisibility(SurfaceView.INVISIBLE);                                
    OpenCVCamView.setVisibility(SurfaceView.VISIBLE);                              
    OpenCVCamView.setCvCameraViewListener(this);                                   
@Override
public void onCameraViewStarted(int width, int height) {
    Log.d(TAG, "on Camera view Started");
    rgba = new Mat (height, width, CvType.CV_8UC4);                         
    rgbaF = new Mat (height, width, CvType.CV_8UC4);                        
    rgbaT = new Mat (height, width, CvType.CV_8UC4);                        
    intMat = new Mat(height, width, CvType.CV_8UC4);                        
    gray = new Mat (height, width, CvType.CV_8UC1);                         
}
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    rgba = inputFrame.rgba();                                               
    Log.d(TAG, "on Camera Frame");
    Core.transpose(rgba,rgbaT);
    Imgproc.resize(rgbaT,rgbaF,rgbaF.size(),0,0,0);
    Core.flip(rgbaF,rgba,1);
    return rgba;
    }
}

我正在使用适用于Android的OpenCV 4.3版。

1 个答案:

答案 0 :(得分:4)

今天在完全相同的兔子洞中找到了自己,然后了解了mOpenCvCameraView.setCameraPermissionGranted()方法,但不太确定该放在哪里。幸运的是,已经有您的问题和另一个答案,描述了如何请求使用相机的权限以及何时调用该方法:Android OpenCV camera example is just showing black screen

这是我对此主题的看法

class MainActivity : AppCompatActivity(), CameraBridgeViewBase.CvCameraViewListener2 {

    companion object {
        private const val REQUEST_CODE_CAMERA_PERMISSION = 101
    }

    private lateinit var mOpenCvCameraView: CameraBridgeViewBase
    private lateinit var mIntermediateMat: Mat
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // this is ViewBinding for Android
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // check for necessary camera permission
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            when {
                ContextCompat.checkSelfPermission(
                    this,
                    Manifest.permission.CAMERA
                ) == PackageManager.PERMISSION_GRANTED -> {
                    // camera permission granted
                    activateOpenCVCameraView()
                }
                shouldShowRequestPermissionRationale(Manifest.permission.CAMERA) -> {
                    // In an educational UI, explain to the user why your app requires this
                    // permission for a specific feature to behave as expected. In this UI,
                    // include a "cancel" or "no thanks" button that allows the user to
                    // continue using your app without granting the permission.
                }
                else -> {
                    // directly ask for the permission.
                    requestPermissions(
                        arrayOf(Manifest.permission.CAMERA),
                        REQUEST_CODE_CAMERA_PERMISSION
                    )
                }
            }
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        // overengineered check for if permission with our request code and permission name was granted
        if (requestCode == REQUEST_CODE_CAMERA_PERMISSION) {
            val indexOfCameraPermission = permissions.indexOf(Manifest.permission.CAMERA)
            if (indexOfCameraPermission != -1) {
                if (grantResults.isNotEmpty()) {
                    if (grantResults[indexOfCameraPermission] == PackageManager.PERMISSION_GRANTED) {
                        Toast.makeText(
                            applicationContext,
                            "Camera permission granted!",
                            Toast.LENGTH_LONG
                        ).show()
                        activateOpenCVCameraView()
                    } else {
                        Toast.makeText(
                            applicationContext,
                            "Camera permission is required to run this app!",
                            Toast.LENGTH_LONG
                        ).show()
                    }
                }
            }
        }
    }

    private fun activateOpenCVCameraView() {
        // everything needed to start a camera preview
        mOpenCvCameraView = binding.cameraView
        mOpenCvCameraView.setCameraPermissionGranted()
        mOpenCvCameraView.setCameraIndex(CameraBridgeViewBase.CAMERA_ID_ANY)
        mOpenCvCameraView.visibility = SurfaceView.VISIBLE
        mOpenCvCameraView.setCvCameraViewListener(this)
        mOpenCvCameraView.enableView()
    }


    override fun onResume() {
        super.onResume()
        // there's no need to load the opencv library if there is no camera preview (I think that sounds reasonable (?))
        if (ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.CAMERA
            ) == PackageManager.PERMISSION_GRANTED
        ) {
            if (!OpenCVLoader.initDebug()) {
                log("Internal OpenCV library not found. Using OpenCV Manager for initialization");
                OpenCVLoader.initAsync(
                    OpenCVLoader.OPENCV_VERSION_3_0_0, this,
                    mLoaderCallback
                )
            } else {
                log("OpenCV library found inside package. Using it!");
                mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
            }
        }
    }

    private val mLoaderCallback: BaseLoaderCallback = object : BaseLoaderCallback(this) {
        override fun onManagerConnected(status: Int) {
            when (status) {
                LoaderCallbackInterface.SUCCESS -> {
                    log("OpenCV loaded successfully")
                    activateOpenCVCameraView()
                }
                else -> super.onManagerConnected(status)
            }
        }
    }

    override fun onCameraViewStarted(width: Int, height: Int) {
        log("onCameraViewStarted")
        mIntermediateMat = Mat()
    }

    override fun onCameraViewStopped() {
        log("onCameraViewStopped")
        // Explicitly deallocate Mats
        mIntermediateMat.release()
    }

    override fun onCameraFrame(inputFrame: CameraBridgeViewBase.CvCameraViewFrame?): Mat {
        log("onCameraFrame")
        val rgba = inputFrame!!.rgba()

        return rgba
    }

    override fun onDestroy() {
        mOpenCvCameraView.disableView()
        super.onDestroy()
    }

    private fun log(message: String) {
        Log.i("MainActivity", message)
    }
}