Why OpenCV Using BGR Colour Space Instead of RGB - opencv

Why OpenCV using BGR colour space instead of RGB. We all know that RGB is the convenient colour model for most of the computer graphics and also the human visual system works in a way that is similar to a RGB colour space. Is there any reason behind OpenCV BGR colour space?.

"The reason why the early developers at OpenCV chose BGR color format is probably that back then BGR color format was popular among camera manufacturers and software providers. E.g. in Windows, when specifying color value using COLORREF they use the BGR format 0x00bbggrr.
BGR was a choice made for historical reasons and now we have to live with it. In other words, BGR is the horse’s ass in OpenCV."

OpenCV reads in images in BGR format (instead of RGB) because when OpenCV was first being developed, BGR color format was popular among camera manufacturers and image software providers. The red channel was considered one of the least important color channels, so was listed last, and many bitmaps use BGR format for image storage. However, now the standard has changed and most image software and cameras use RGB format, which is why, in programs, it's good practice to initially convert BGR images to RGB before analyzing or manipulating any images.

Why? For historical reasons. In 1987, Microsoft Windows ran on the IBM PS/2, and an early IBM video display controller, VGA, made use of the INMOS 171/176 RAMDAC chip, which was easier to use when images were stored in BGR format.
See details at
Why BGR color order - Retrocomputing Stack Exchange

Related

RGB, HSV concept

I found an image stating the difference between RGB and HSV color spaces. But from the image, it looks like that they are just different ways of representing the same color, yet when we display them on our screen(e.g. using OpenCV) they look different. I mean though HSV space separates luminance from the color, the actual color should remain same.
Also for displaying an HSV image on the laptop screen, we will need the RGB values, what are those RGB values?
You said it yourself:
"they are just different ways of representing the same color"
Since they are simply different representations, you can convert between the formats. There are already SO posts on that: here, and this answer here.
RGB and HSV are useful in different applications. HSV seperates the color information from brightness information, which can be useful when comparing colors in image processing, for example. RBG is typically how screens display images.
As Cris said, you should not see these displayed differently.

Which color matching functions does OpenCV use for its RGB/BGR color space?

I'm using OpenCV 3.0, but my question should be version agnostic. I'm wondering which of the many RGB color space OpenCV uses by default.
That is, for images in the default representation, BGR, which RGB space does OpenCV use?
I suspect they are either the CIE 1931 XYZ functions:
or the CIE 1931 RGB functions:
Heads up: this question is mirrored here (awaiting moderation, as of right now). I'll make sure any knowledge is shared between them.
It turns out that color matching functions are a capture device and display device problem. Look at this relevant section of the sRGB wiki page
Due to the standardization of sRGB on the Internet, on computers, and on printers, many low- to medium-end consumer digital cameras and scanners use sRGB as the default (or only available) working color space. As the sRGB gamut meets or exceeds the gamut of a low-end inkjet printer, an sRGB image is often regarded as satisfactory for home use. However, consumer-level CCDs are typically uncalibrated, meaning that even though the image is being labeled as sRGB, one can't conclude that the image is color-accurate sRGB.
OpenCV can be used to convert to and from color spaces or derive color space coordinates with the right math. But OpenCV does not have a "default" set of color matching functions. If your camera captures in space X (say, CIE XYZ) and your display device or printer also displays in space X, then OpenCV can be used to process the data between with no consideration to the spaces. However, if the display device displays in a different space Y (say, Adobe RGB), then OpenCV can be used to translate the image from space X to space Y.
Although OpenCV is mostly indifferent color space for RGB, the exception is cv::cvtColor which transforms between well defined color spaces and the native OpenCV RGB. From the coefficients used, we can see it uses the sRGB space.

How do I create an RGB CIImage from 3 8-bit gray images?

I have 3 CIImage objects that are gray 8-bpp images that are meant to be the 8-bit R, G, and B channels of a new image. Aside from low-level image pixel data operations, is there a way to construct the CIImage (from filters or some other easier way)
I realize I can do this by looping through the pixels of a new RGB image and setting it from the gray channels I have -- I was wondering if there was a more idiomatic way to work with channels.
For example, in Pillow for Python, it's Image.merge([rChannel, gChannel, bChannel]) -- I know how to code the pixel access way if there is no built in way.
The book, Core Image for Swift, covers how to do this and provides the code to do it here:
https://github.com/FlexMonkey/Filterpedia/blob/master/Filterpedia/customFilters/RGBChannelCompositing.swift
The basic idea is that you need to provide a color kernel function in GPU shader language and wrap it in a CIFilter subclass.
NOTE: The code is not copied here because it's under GPL, which is an incompatible license with StackOverflow answers. You can follow the link if you want to see how it's done, and use it if it's compatible with your license.

Does OpenCV have functions to handle non-linearities in sRGB color space?

I am wondering whether OpenCV has functions to handle the non-linearities in the sRGB color space.
Say I want to convert an JPEG image from sRGB color space into XYZ color space. As specified in this Wiki page, one needs to first undo the nonlinearities to convert to linear RGB space, and then multiply with the 3x3 color transform matrix. However, I couldn't find any such discussions in the cvtColor documentation. Did I miss something?
Thanks a lot in advance!
It's not explicitly stated in the documentation, so you're not missing anything, but OpenCV does not perform gamma correction in its RGB2XYZ/BGR2XYZ color conversions. You can confirm this by looking at the source code for cvtColor in
<OpenCV_dir>/modules/imgproc/src/color.cpp
If you look at the RGB <-> XYZ section you'll see that the input RGB values are simply multiplied by the coefficient matrix.
I have also not found any existing method to perform gamma correction on an RGB image.
Interestingly, a custom RGB -> XYZ conversion is done as a preliminary step for converting to both L*a*b* and L*u*v*, and in both cases it performs gamma correction.
Unfortunately, this isn't accessible from RGB2XYZ code, but you might be able to reuse it in your own code. I've also seen several code samples on the web, mostly using look-up tables for CV_8U depth images.

Convert All Images to RGB for Transfer

I am using JNA to access openCV, in my application I have one function that returns an array of RGB values to java for display which is fine if the image is actually uses rgb color space but if the image is hsv or a binary image it produces odd behavior artifacts how i can detect what color space it is using and convert everything to rgb before transfer and convert them to rgb if they arent?
You can't detect if an image is rgb or not by direct examination of the the three buffers. You need to know what format it's in before making it available to another process or app.
I suggest you decide to use rgb for all your interprocess buffers and ensure that all the images are converted to rgb in each originating process.
in Opencv use "CvtColor" to get the native bgr into rgb. From other apps - if they don't support image conversion - then you can use cvconvert to get them all into rgb if you need to.
You can also use "Merge" and "Mixchannels" to make simple rgb to bgr without any fuss and in-place.
in 2.2 there is a better rgb to hsv fuinction which uses all 256 values for hue. it is better than the older one.
docs here: http://opencv.willowgarage.com/wiki/

Resources