2

I have read at several places (source, source) that OpenCV uses BGR color format by default.

But I am writing a class to detect a blob of a certain color (red) in an image (following the Color Blob Detection sample). So in the onCameraFrame(CvCameraViewFrame inputFrame) function, we return the value inputFrame.rgba(). According to the documentation,

rgba() This method returns RGBA Mat with frame

So I assumed that my rgbaFrame, which is the variable storing the value of inputFrame.rgba() in my program, contains the Mat in RGBA format.

But when I run the app, the red color in the original image appeared to be bluish in the rgbaFrame Mat I wrote to the external SD card. So apparently, the Mat is in BGR format, because red is appearing to be blue. (This is discussed in the comments of this question.)

So I changed my cvtColorfunction from

Imgproc.cvtColor(rgbaFrame, hsvImage, Imgproc.COLOR_RGB2HSV_FULL);

to

Imgproc.cvtColor(rgbaFrame, hsvImage, Imgproc.COLOR_BGR2HSV_FULL);

But nothing changed when I run the program. Red in original image still appears blue in the captured frame.

So now I am looking for a way to convert RGB to BGR format, to try and see if that helps solve my problem. But have failed to find one. How do I convert BGR to RGB? Please share if you have any other suggestions for me.

  • original screenshot from which camera frame is captured:

enter image description here

  • rgbaFrame.jpg (because I did Highgui.imwrite("/mnt/sdcard/DCIM/rgbaFrame.jpg", rgbaFrame);//check)

enter image description here

Community
  • 1
  • 1
Solace
  • 8,612
  • 22
  • 95
  • 183
  • 1
    Well, `rgbaFrame` will remain unchanged after `cvtColor` because you're writing results to `hsvImage`. Can you show us how resulting `hsvImage` looks like? – Dmitry Zaytsev Dec 09 '15 at 14:52
  • @DmitryZaitsev Oh yes, you can see all the images and the code [here in this question.](http://stackoverflow.com/questions/34170856/trying-to-detect-blue-color-from-image-using-opencv-and-getting-unexpected-resu). Please let me know if you think I should post the image in this question as well. – Solace Dec 09 '15 at 15:05
  • @DmitryZaitsev and I changed to `Imgproc.cvtColor(rgbaFrame, hsvImage, Imgproc.COLOR_BGR2HSV_FULL);` based on the assumption that `rgbaFrame` is already in BGR format. The function `Imgproc.cvtColor(rgbaFrame, hsvImage, Imgproc.COLOR_BGR2HSV_FULL);` just changes the the BGR color space to HSV color space right? – Solace Dec 09 '15 at 15:06
  • @DmitryZaitsev Please don't get confused from the other question I pointed to, the question labelled '(2)' is already solved. You can see the HSV image in the Edit to the question. – Solace Dec 09 '15 at 15:13
  • You can convert from bgr to rgb, or viceversa, with COLOR_BGR2RGB or similar. However, it seems that you're saving the HSV image. In this case, you need to convert back the image to bgr befor saving – Miki Dec 09 '15 at 17:39
  • Did you solved the issue? – Kanagalingam Mar 20 '18 at 10:17
  • I think the issue is that OpenCV uses BGR by default, however, Android `frame.rgba()` implementation returns RGB (possibly for compliance with imageview and other Android components). However, the OpenCV function `imwrite` still requires BGR, therefore if you save the image without first converting it to BGR then the blue and red channels are saved incorrectly (swapped). You can call `cvtcolor` with `COLOR_RGB2BGR` before saving to a file. – mcy Jul 26 '21 at 08:30

1 Answers1

0

OpenCV uses BGR by default, however, Android frame.rgba() implementation returns RGB (possibly for compliance with imageview and other Android components). However, the OpenCV function imwrite still requires BGR, therefore if you save the image without first converting it to BGR then the blue and red channels are saved incorrectly (swapped), because the Mat file of the frame has red channel in index 0 (RGB) whereas imwrite writes index 0 as blue (BGR). Similarly the frame has blue channel in index 2 whereas imwrite writes index 2 as red. You can call cvtcolor with COLOR_RGB2BGR before saving to a file.

/**
 * Callback method that is called on every frame of the CameraBridgeViewBase class of OpenCV
 */
override fun onCameraFrame(inputFrame: CameraBridgeViewBase.CvCameraViewFrame?): Mat {
    inputFrame?.let { currentFrame ->

        val currentFrameMat = currentFrame.rgba()

            // save the RGB2BGR converted version
            val convertedMat = Mat()
            Imgproc.cvtColor(currentFrameMat, convertedMat, Imgproc.COLOR_RGB2BGR)
            Imgcodecs.imwrite(imageFilePath, convertedMat)
        
        return currentFrameMat
    }
    return Mat()
}
mcy
  • 1,209
  • 6
  • 25
  • 37