为什么rgba()方法返回的Mat似乎是BGR格式而不是RGBA格式?

时间:2015-12-09 14:08:40

标签: android opencv image-processing opencv3.0 opencv4android

我已经在几个地方(sourcesource)阅读了OpenCV默认使用BGR颜色格式。

但我正在编写一个类来检测图像中某种颜色(红色)的斑点(在Color Blob Detection sample之后)。因此,在onCameraFrame(CvCameraViewFrame inputFrame)函数中,我们返回值inputFrame.rgba()。根据{{​​3}},

  

rgba()此方法返回带有框架

RGBA Mat

所以我假设我的rgbaFrame,即在我的程序中存储inputFrame.rgba()值的变量,包含RGBA格式的Mat。

但是当我运行应用程序时,原始图像中的红色在我写入外部SD卡的rgbaFrame Mat中显得偏蓝。 显然,Mat是BGR格式,因为红色看起来是蓝色。(这在documentation讨论)

所以我从

更改了我的cvtColor功能
Imgproc.cvtColor(rgbaFrame, hsvImage, Imgproc.COLOR_RGB2HSV_FULL);

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

但是当我运行程序时没有任何改变。原始图像中的红色在捕获的帧中仍显示为蓝色。

所以现在我正在寻找一种将RGB转换为BGR格式的方法,试着看看是否有助于解决我的问题。但未能找到一个。 如何将BGR转换为RGB?如果您对我有任何其他建议,请分享。

  • 捕获相机框架的原始屏幕截图:

comments of this question.

  • rgbaFrame.jpg(因为我做了Highgui.imwrite("/mnt/sdcard/DCIM/rgbaFrame.jpg", rgbaFrame);//check

enter image description here

1 个答案:

答案 0 :(得分:0)

OpenCV 默认使用 BGR,但是,Android frame.rgba() 实现返回 RGB(可能是为了符合 imageview 和其他 Android 组件)。但是,OpenCV 函数 imwrite 仍然需要 BGR,因此如果您在未先将其转换为 BGR 的情况下保存图像,那么蓝色和红色通道将被错误地保存(交换),因为帧的 Mat 文件中包含红色通道索引 0 (RGB) 而 imwrite 将索引 0 写为蓝色 (BGR)。类似地,框架在索引 2 中有蓝色通道,而 imwrite 将索引 2 写为红色。在保存到文件之前,您可以使用 cvtcolor 调用 COLOR_RGB2BGR

/**
 * 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()
}