Search code examples
androidopencvresolutionedge-detection

OpenCV captured image resolution vs Fotoapparat


I'm working on a project where we need to recognise bubbles as part of an exam. We've been testing different approaches to image taking based on requirements (we need to overlay shapes on the live camera stream) and below are the results.

As we can see, when taking the images directly from Fotoapparat, the canny detection works much much better than the OpenCV implementation. I have tried to adjust the camera resolution (by extending JavaCameraView) amongst many other things, but none of them seem to work, OpenCV captures always perform poorly.

Can anyone point me in the right direction towards capturing one of the frames from OpenCV with the highest possible resolution available to the phone?

Thanks in advance :)

RESULTS:

OpenCV - Raw ROI

enter image description here

OpenCV - Canny transformation on ROI

enter image description here

Fotoapparat - Raw ROI (Compressed 31% so i could upload)

enter image description here

Fotoapparat - Canny transformation on ROI

enter image description here


Solution

  • I finally figured it out!

    What was happening was that when trying to extract a frame from OpenCV's onCameraFrame it was defaulting to a tiny resolution (and affected by screen size) as it was effectively taking a screenshot of what was on the screen at the time.

    The solution was to implement the camera.takePicture in my own class which implemented JavaCameraView (similar to the one shown in the question here), and before taking the picture, selecting the highest possible resolution available on the device.

    Code is as follows:

        fun takePic(jpgCallback: Camera.PictureCallback) {
            val params = mCamera.parameters
            params.jpegQuality = 100 //doesn't hurt to be sure
    
            val supportedSizes = params.supportedPictureSizes
            if (supportedSizes.isNullOrEmpty().not()) {
                var w = 0
                var h = 0
                for (size in supportedSizes) {
                    if (size.width > w || size.height > h) {
                        w = size.width
                        h = size.height
                    }
                }
    
                Log.e("----", "Using largest supported size... w: $w // h: $h")
                params.setPictureSize(w, h)
            }
            mCamera.parameters = params
            mCamera.takePicture(null, null, jpgCallback)
        }