0

I want to draw a rectangle with opencv from the image acquired by camerax and display it in imageview.

The top of the attached image is Image View and the bottom is Preview View.

ImageView Noise

ImageView Black

An image with noise or a completely black image is output.

I suspect there is a problem with the process of converting ImageProxy to Mat or Bitmap.

class MyImageAnalyzer(previewview:PreviewView,imageview:ImageView) : ImageAnalysis.Analyzer {
var previewView:PreviewView = previewview
var imageView:ImageView = imageview

override fun analyze(image: ImageProxy) {
    /* Create cv::mat(RGB888) from image(NV21) */
    val matOrg = getMatFromImage(image)

    /* Fix image rotation (it looks image in PreviewView is automatically fixed by CameraX???) */
    val mat = fixMatRotation(matOrg)

    /* Do some image processing */
    val matOutput = Mat(mat.rows(), mat.cols(), mat.type())

    /* Draw something for test */
    Imgproc.rectangle(
        matOutput,
        Rect(10, 10, 100, 100),
        Scalar(255.0, 0.0, 0.0)
    )

    /* Convert cv::mat to bitmap for drawing */
    val bitmap =
        Bitmap.createBitmap(matOutput.cols(), matOutput.rows(), Bitmap.Config.ARGB_8888)
    Utils.matToBitmap(matOutput, bitmap)

    /* Display the result onto ImageView */
    Handler(Looper.getMainLooper()).post {
        imageView.setImageBitmap(bitmap)
    }

    /* Close the image otherwise, this function is not called next time */
    image.close()
}

private fun getMatFromImage(image: ImageProxy): Mat {
    /* https://stackoverflow.com/questions/30510928/convert-android-camera2-api-yuv-420-888-to-rgb */
    val yBuffer: ByteBuffer = image.planes[0].buffer
    val uBuffer: ByteBuffer = image.planes[1].buffer
    val vBuffer: ByteBuffer = image.planes[2].buffer
    val ySize: Int = yBuffer.remaining()
    val uSize: Int = uBuffer.remaining()
    val vSize: Int = vBuffer.remaining()
    val nv21 = ByteArray(ySize + uSize + vSize)
    yBuffer.get(nv21, 0, ySize)
    vBuffer.get(nv21, ySize, vSize)
    uBuffer.get(nv21, ySize + vSize, uSize)
    val yuv = Mat(image.height + image.height / 2, image.width, CvType.CV_8UC1)
    yuv.put(0, 0, nv21)
    val mat = Mat()
    Imgproc.cvtColor(yuv, mat, Imgproc.COLOR_YUV2RGB_NV21, 3)
    return mat
}

private fun fixMatRotation(matOrg: Mat): Mat {
    val mat: Mat
    when (previewView.display.rotation) {
        Surface.ROTATION_0 -> {
            mat = Mat(matOrg.cols(), matOrg.rows(), matOrg.type())
            Core.transpose(matOrg, mat)
            Core.flip(mat, mat, 1)
        }
        Surface.ROTATION_90 -> mat = matOrg
        Surface.ROTATION_270 -> {
            mat = matOrg
            Core.flip(mat, mat, -1)
        }
        else -> {
            mat = Mat(matOrg.cols(), matOrg.rows(), matOrg.type())
            Core.transpose(matOrg, mat)
            Core.flip(mat, mat, 1)
        }
    }
    return mat
}

}

I hope the processed image is displayed smoothly on the ImageView

Haru
  • 1
  • 1
  • Please don't use links. A link may become broken, making the question useless for future users. Add the image to the question by using the Image option from the toolbar. – gioravered Jan 05 '23 at 08:32
  • 1
    does this issue _require_ opencv to be demonstrated? you describe what sounds like _acquisition_ issues, yet you don't use OpenCV for acquisition. [mre] please. also, if you haven't, please take the [tour] and review [ask] – Christoph Rackwitz Jan 05 '23 at 09:27
  • I am using a toolbar button to insert the image. I am getting the image with CameraX, but there is no problem in acquiring the image, and there seems to be a problem in the process of converting to mat or bitmap. – Haru Jan 06 '23 at 00:21

0 Answers0