Skip to main content

Overview

Color spaces are different ways of representing colors numerically. OpenCV supports numerous color space conversions through the cvtColor() function.

BGR Color Space

Default in OpenCV

OpenCV uses BGR (Blue-Green-Red) as its default color format:
Mat img = imread("image.jpg");  // Loaded as BGR

// Access pixel
Vec3b pixel = img.at<Vec3b>(y, x);
uchar blue = pixel[0];
uchar green = pixel[1];
uchar red = pixel[2];
Most other libraries (including matplotlib, PIL) use RGB order. Always convert when needed.

Common Color Spaces

RGB/BGR

Use case: Display, most common representation
// BGR to RGB
Mat rgb;
cvtColor(bgr, rgb, COLOR_BGR2RGB);

// RGB to BGR  
cvtColor(rgb, bgr, COLOR_RGB2BGR);

Grayscale

Use case: Simplify processing, reduce computation
// Color to grayscale
Mat gray;
cvtColor(img, gray, COLOR_BGR2GRAY);

// Grayscale to color (creates 3 identical channels)
cvtColor(gray, img, COLOR_GRAY2BGR);

HSV (Hue-Saturation-Value)

Use case: Color-based segmentation, lighting-independent processing
  • Hue: Color type (0-179 in OpenCV)
  • Saturation: Color intensity (0-255)
  • Value: Brightness (0-255)
Mat hsv;
cvtColor(img, hsv, COLOR_BGR2HSV);

// Color range detection
Mat mask;
inRange(hsv, Scalar(0, 100, 100), Scalar(10, 255, 255), mask);

LAB (Lab*)

Use case: Perceptually uniform, skin detection
  • L: Lightness (0-100)
  • a: Green-Red axis
  • b: Blue-Yellow axis
Mat lab;
cvtColor(img, lab, COLOR_BGR2Lab);

// Useful for color-based operations
vector<Mat> channels;
split(lab, channels);
Mat L = channels[0];  // Lightness only

YCrCb

Use case: Video compression, skin detection
  • Y: Luminance
  • Cr: Red-difference
  • Cb: Blue-difference
Mat ycrcb;
cvtColor(img, ycrcb, COLOR_BGR2YCrCb);

Color Conversion

Basic Conversion

// Function signature
void cvtColor(InputArray src, OutputArray dst, int code);

// Examples
cvtColor(bgr, gray, COLOR_BGR2GRAY);
cvtColor(bgr, hsv, COLOR_BGR2HSV);
cvtColor(hsv, bgr, COLOR_HSV2BGR);

Common Conversion Codes

FromToCode
BGRGrayCOLOR_BGR2GRAY
BGRRGBCOLOR_BGR2RGB
BGRHSVCOLOR_BGR2HSV
BGRLABCOLOR_BGR2Lab
BGRYCrCbCOLOR_BGR2YCrCb
HSVBGRCOLOR_HSV2BGR
GrayBGRCOLOR_GRAY2BGR

Practical Examples

Color Detection

// Detect red objects
Mat hsv, mask;
cvtColor(img, hsv, COLOR_BGR2HSV);

// Red is at both ends of hue range
Mat mask1, mask2;
inRange(hsv, Scalar(0, 100, 100), Scalar(10, 255, 255), mask1);
inRange(hsv, Scalar(170, 100, 100), Scalar(180, 255, 255), mask2);
mask = mask1 | mask2;

Lighting Normalization

// Separate intensity from color
Mat lab;
cvtColor(img, lab, COLOR_BGR2Lab);

vector<Mat> channels;
split(lab, channels);

// Normalize L channel
equalizeHist(channels[0], channels[0]);

merge(channels, lab);
cvtColor(lab, img, COLOR_Lab2BGR);

Skin Detection

Mat ycrcb;
cvtColor(img, ycrcb, COLOR_BGR2YCrCb);

// Skin color range in YCrCb
Mat skinMask;
inRange(ycrcb, 
        Scalar(0, 133, 77), 
        Scalar(255, 173, 127), 
        skinMask);

Color Space Selection

HSV

  • Color-based segmentation
  • Lighting-independent tracking
  • Hue provides rotation invariance

LAB

  • Perceptually uniform
  • Separate luminance from color
  • Better for color difference calculations

YCrCb

  • Video compression
  • Skin detection
  • Chroma subsampling

Grayscale

  • Simplest representation
  • Fastest processing
  • Use when color not needed

Best Practices

Conversion Tips

  1. Minimize conversions: Convert once, cache result
  2. Choose appropriate space: Match algorithm requirements
  3. Remember value ranges: HSV hue is 0-179, not 0-255
  4. Consider precision: Use CV_32F for sensitive operations

Performance

// Avoid repeated conversion in loops
Mat hsv;
cvtColor(img, hsv, COLOR_BGR2HSV);  // Convert once

for(int i = 0; i < 1000; i++) {
    // Use hsv directly
    processImage(hsv);
}

See Also