70

I was surprised when I couldn't find anything in OpenCV documentation describing - with words - what the various types stand for, and Googling wasn't much help either. I know that CV_8UC1 is gray-scale, but what does CV_8UC3 stand for? Is it RGB? Or YUV?

Also, what about the other definitions from types_c.h (they also lack comments). Is there a pattern to what the naming convention is? Can I interpret from their names to what their features are, like colors, etc.?

#define CV_8UC1 CV_MAKETYPE(CV_8U,1)
#define CV_8UC2 CV_MAKETYPE(CV_8U,2)
#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
#define CV_8UC4 CV_MAKETYPE(CV_8U,4)
#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))

#define CV_8SC1 CV_MAKETYPE(CV_8S,1)
#define CV_8SC2 CV_MAKETYPE(CV_8S,2)
#define CV_8SC3 CV_MAKETYPE(CV_8S,3)
#define CV_8SC4 CV_MAKETYPE(CV_8S,4)
#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n))

#define CV_16UC1 CV_MAKETYPE(CV_16U,1)
#define CV_16UC2 CV_MAKETYPE(CV_16U,2)
#define CV_16UC3 CV_MAKETYPE(CV_16U,3)
#define CV_16UC4 CV_MAKETYPE(CV_16U,4)
#define CV_16UC(n) CV_MAKETYPE(CV_16U,(n))

#define CV_16SC1 CV_MAKETYPE(CV_16S,1)
#define CV_16SC2 CV_MAKETYPE(CV_16S,2)
#define CV_16SC3 CV_MAKETYPE(CV_16S,3)
#define CV_16SC4 CV_MAKETYPE(CV_16S,4)
#define CV_16SC(n) CV_MAKETYPE(CV_16S,(n))

#define CV_32SC1 CV_MAKETYPE(CV_32S,1)
#define CV_32SC2 CV_MAKETYPE(CV_32S,2)
#define CV_32SC3 CV_MAKETYPE(CV_32S,3)
#define CV_32SC4 CV_MAKETYPE(CV_32S,4)
#define CV_32SC(n) CV_MAKETYPE(CV_32S,(n))

#define CV_32FC1 CV_MAKETYPE(CV_32F,1)
#define CV_32FC2 CV_MAKETYPE(CV_32F,2)
#define CV_32FC3 CV_MAKETYPE(CV_32F,3)
#define CV_32FC4 CV_MAKETYPE(CV_32F,4)
#define CV_32FC(n) CV_MAKETYPE(CV_32F,(n))

#define CV_64FC1 CV_MAKETYPE(CV_64F,1)
#define CV_64FC2 CV_MAKETYPE(CV_64F,2)
#define CV_64FC3 CV_MAKETYPE(CV_64F,3)
#define CV_64FC4 CV_MAKETYPE(CV_64F,4)
#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n))
sashoalm
  • 75,001
  • 122
  • 434
  • 781
  • Related - https://stackoverflow.com/questions/13428689/whats-the-difference-between-cvtype-values-in-opencv – sashoalm May 30 '19 at 08:46

3 Answers3

87

As noted in the documentation

Any primitive type from the list can be defined by an identifier in the form CV_<bit-depth>{U|S|F}C(<number_of_channels>)

where U is unsigned integer type, S is signed integer type, and F is float type.

so CV_8UC3 is an 8-bit unsigned integer matrix/image with 3 channels. Although it is most common that this means an RGB (or actually BGR) image, it does not mandate it. It simply means that there are three channels, and how you use them is up to you and your application.

Hannes Ovrén
  • 21,229
  • 9
  • 65
  • 75
  • 1
    "it does not mandate it" - but I assume functions like `cv::imread` will fill them with RGB values? – sashoalm Nov 28 '14 at 07:49
  • 1
    That depends on the flags passed to `imread`. But if you pass `CV_LOAD_IMAGE_COLOR` then the output should always be BGR, which is the color format OpenCV usually uses. – Hannes Ovrén Nov 28 '14 at 07:52
  • 3
    What I meant in my post was that just because a matrix/image has the type `CV_8UC3` does not necessarily mean it is BGR. It might just as well be HSV, or something that is not color information at all. – Hannes Ovrén Nov 28 '14 at 07:53
  • @HannesOvrén Exactly. It just defines the actual structure (i.e. bytes per pixel, how to access them, the actual stride etc.). It doesn't force you to interpret them in any specific way though (colors, multiple grayscale images, yuv, ...). – Mario Nov 28 '14 at 08:11
  • @sashoalm: actually more complicated: C++ will fill them with RGB, but Python uses numpy, and will fill with BGR. – Michał Leon Jul 07 '15 at 09:24
14

The naming pattern depicts how the data is actually laid out in the PC memory and is not directly related to the image type. Actually, data layout and image type are decoupled.

You have probably found out the meaning for the CV_XX pattern (ie, data layout).

For the imaged data type, if you ask OpenCV to load an image as a colour image, it will load it as a BGR image and lay out its data as CV_8UC3. A few things to be aware of:

  • yes, the default channel ordering is BGR and not RGB. This is a legacy ordering because digital video feeds from webcams seemed to follow this order when OpenCV 1.xx was under development;
  • you can use type conversion functions from the module imgproc, namely cv::cvtColor(). All data layouts and image types are not compatible though, check the doc;
  • the alpha channel is usually ignored. By ignoring, I mean that cv::imwrite() will write a 3 channel image without alpha for example. Most of the processing functions will either be specific to single channel images or apply the same processing to all the channels equally;
  • when a function accepts an (alpha-)mask, it is usually an optional parameter of type CV_8UC1 that defaults to an empty matrix.
sansuiso
  • 9,259
  • 1
  • 40
  • 58
  • I assume that CV_8UC4 would have the alpha channel? – sashoalm Nov 28 '14 at 07:53
  • Yes, the alpha channel will be stored in the 4th channel. I'm pretty sure that `cv::imwrite()` will **ignore** it though, and it needs to be checked for `cv::imwrite()`. Other functions will usually either only work with single channel images or will apply the same processing to all the channels equally. – sansuiso Nov 28 '14 at 07:55
  • Ok, I checked, `cv::imread()` can either load the alpha channel (option: `as_is`) or drop it (option: `load_colour`). Example here: http://docs.opencv.org/doc/tutorials/introduction/display_image/display_image.html – sansuiso Nov 28 '14 at 07:59
0

8UC3 helps you access the RGB data. And it is not limited to just images. You can use it for accessing the RGB data in Point Clouds as well. If you pass the RGB value as a Matrix of type 8UC3, you can then show this value as color in the viz module and display an RGB Pointcloud.

Giant Cloud
  • 83
  • 2
  • 11