Digital image processing - mutual conversion between Lab, YCbCr, HSV, RGB

Lab

The "Lab" image format usually refers to the CIELAB color space, also known as the Lab color space. It is a device-independent color space used to describe the color of human visual perception, which is different from the common RGB and CMYK color spaces. CIELAB was defined by the International Commission on Illumination (CIE) in 1976 to more accurately represent the human eye's perception of color.
CIELAB includes three channels: L (luminance), a (color components from green to red), and b (color components from blue to yellow). The main advantage of this color space is that it tries to simulate the way the human eye perceives colors, such that colors that are closer in Lab space are also visually more similar. This makes the Lab color space useful in many color-related applications, such as image processing, color correction, and color matching.
However, it's important to note that the Lab image format itself is not a common image file format such as JPEG, PNG, or GIF. In contrast, the Lab color space is often used as an intermediate color space in image processing to aid in color correction, color adjustment, and other color-related operations. To represent the Lab color space on a computer, the values ​​of the L, a, and b channels are usually represented using floating-point numbers.
insert image description here

YCbCr

YCbCr is a color space used for digital image and video coding, which is different from RGB color space. YCbCr is often used in image and video compression, transmission, and digital media processing because it has the property of separating color and brightness information that is perceived differently by the human eye, which can reduce the amount of data transmission while maintaining visual quality.
YCbCr consists of three components:
Y (brightness): Indicates the brightness component of the image. This component corresponds to the brightness perception of the image by the human eye.
Cb and Cr (Color Difference): These two components represent the chrominance or color difference components in the color information. Cb represents the difference between blue and brightness, while Cr represents the difference between red and brightness. This separation allows color information to be separated from luminance information, allowing compression without significantly affecting visual perception.
YCbCr is widely used in digital media technologies such as JPEG image compression, video coding (such as MPEG and H.264), and digital television broadcasting. Many image and video formats use the YCbCr color space to store data because it reduces the amount of data stored and transmitted while preserving image quality. In these formats, the color information of the image is mapped to the Cb and Cr channels, while the luminance information is kept in the Y channel.
insert image description here

HSV

It is based on how the human visual system perceives color and is different from the RGB and CMYK color spaces. HSV stands for Hue, Saturation, and Value, and it provides an intuitive way to describe different aspects of color.
The following are the three components of the HSV color space:

  1. Hue: Hue represents the basic properties of a color, that is, the name of the color we often say, such as red, green, blue, etc. The value range of hue is usually 0 to 360
    degrees, which divides the entire color circle into different colors.
  2. Saturation: Saturation indicates the purity or vividness of a color. A less saturated color will be darker or washed out, while a more saturated color will be more vibrant. Saturation typically ranges in value from 0% (gray) to 100% (fully saturated).
  3. Brightness (Value): Brightness indicates how light or dark a color is. Higher brightness values ​​indicate brighter colors, while lower values ​​indicate darker colors. Brightness typically ranges from 0% (black) to 100% (white).
    The HSV color space is often used in image processing and computer graphics because it provides a more intuitive way to control the appearance of colors. Compared with the RGB color space, HSV is more suitable for adjusting the saturation and lightness of colors without considering the complex interaction between colors.
    insert image description here

the code

First, define the data structure of these color spaces. In order to facilitate reading and writing of images, here we use OpenCV to read in images, and convert BGR to RGB after reading.

#pragma once
#include <iostream>
#include <algorithm>
#include <opencv2/opencv.hpp>
struct Lab
{
    
    
	float L;
	float a;
	float b;
};

struct YCbCr
{
    
    
    float Y;
    float Cb;
    float Cr;
};

struct HSV
{
    
    
	int h;
	double s;
	double v;
};

struct BGR
{
    
    
	float b;
	float g;
	float r;
};

Implementation code

void BGR_YCbCr(BGR &bgr, YCbCr& y)
{
    
    
    y.Y = 0.257 * bgr.r + 0.564 * bgr.g + 0.098 * bgr.b + 16;
    y.Cb = -0.148 * bgr.r - 0.291 * bgr.g + 0.439 * bgr.b + 128;
    y.Cr = 0.439 * bgr.r - 0.368 * bgr.g - 0.071 * bgr.b + 128;
}

void BGR_Lab(BGR &bgr, Lab& lab)
{
    
    
    double X, Y, Z;
    double Fx = 0, Fy = 0, Fz = 0;
    double b = bgr.b / 255.00;
    double g = bgr.g / 255.00;
    double r = bgr.r / 255.00;


    // gamma 2.2
    if (r > 0.04045)
        r = pow((r + 0.055) / 1.055, 2.4);
    else
        r = r / 12.92;
    if (g > 0.04045)
        g = pow((g + 0.055) / 1.055, 2.4);
    else
        g = g / 12.92;
    if (b > 0.04045)
        b = pow((b + 0.055) / 1.055, 2.4);
    else
        b = b / 12.92;
    // sRGB
    X = r * 0.436052025 + g * 0.385081593 + b * 0.143087414;
    Y = r * 0.222491598 + g * 0.716886060 + b * 0.060621486;
    Z = r * 0.013929122 + g * 0.097097002 + b * 0.714185470;
    // XYZ range: 0~100
    X = X * 100.000;
    Y = Y * 100.000;
    Z = Z * 100.000;
    // Reference White Point
    //2度视场 D50光源三刺激值
    double ref_X = 96.4221;
    double ref_Y = 100.000;
    double ref_Z = 82.5211;


    X = X / ref_X;
    Y = Y / ref_Y;
    Z = Z / ref_Z;


    // Lab
    if (X > 0.008856)
        Fx = pow(X, 1 / 3.000);
    else
        Fx = (7.787 * X) + (16 / 116.000);
    if (Z > 0.008856)
        Fz = pow(Z, 1 / 3.000);
    else
        Fz = (7.787 * Z) + (16 / 116.000);
    if (Y > 0.008856)
    {
    
    
        Fy = pow(Y, 1 / 3.000);
        lab.L = (116.000 * Fy) - 16.0 + 0.5;
    }
    else
    {
    
    
        Fy = (7.787 * Y) + (16 / 116.000);
        lab.L = 903.3 * Y;
    }

    lab.a = 500.000 * (Fx - Fy) + 0.5;
    lab.b = 200.000 * (Fy - Fz) + 0.5;
}

bool IsEquals(double val1, double val2)
{
    
    
	return fabs(val1 - val2) < 0.001;
}

void BGR_HSV(BGR& bgr, HSV& hsv)
{
    
    
	double b, g, r;
	double h, s, v;
	double min, max;
	double delta;

	b = bgr.b / 255.0;
	g = bgr.g / 255.0;
	r = bgr.r / 255.0;

	if (r > g)
	{
    
    
		max = std::max(r, b);
		min = std::min(g, b);
	}
	else
	{
    
    
		max = std::max(g, b);
		min = std::min(r, b);
	}

	v = max;
	delta = max - min;

	if (IsEquals(max, 0))
		s = 0.0;
	else
		s = delta / max;

	if (max == min)
		h = 0.0;
	else
	{
    
    
		if (IsEquals(r, max) && g >= b)
		{
    
    
			h = 60 * (g - b) / delta + 0;
		}
		else if (IsEquals(r, max) && g < b)
		{
    
    
			h = 60 * (g - b) / delta + 360;
		}
		else if (IsEquals(g, max))
		{
    
    
			h = 60 * (b - r) / delta + 120;
		}
		else if (IsEquals(b, max))
		{
    
    
			h = 60 * (r - g) / delta + 240;
		}
	}

	hsv.h = (int)(h + 0.5);
	hsv.h = (hsv.h > 359) ? (hsv.h - 360) : hsv.h;
	hsv.h = (hsv.h < 0) ? (hsv.h + 360) : hsv.h;
	hsv.s = s;
	hsv.v = v;
}

BGR BGR_value(cv::Mat& cv_src)
{
    
    
    cv::Scalar s = cv::mean(cv_src);
    BGR bgr;
    bgr.b = s[0];
    bgr.g = s[1];
    bgr.r = s[2];

    return bgr;
}

Guess you like

Origin blog.csdn.net/matt45m/article/details/132423065