Digital image processing (5) HSV transformation

Title: Convert from RGB color representation to HSV color representation.
The international standard test image Lena is used.
H (Hue) chromaticity: It is the name of the color that is usually called, such as red, blue, green. Hue and value correspond to the following table:

red yellow green green blue magenta red
0 ° 0\degree 60 ° 60\degree 60° 120 ° 120\degree 120° 180 ° 180\degree 180° 240 ° 240\degree 240° 300 ° 300\degree 300° 360 ° 360\degree 360°

S (Saturation) Saturation: refers to the purity of the color, the lower the saturation, the darker the color, 0 ≤ S ≤ 1 0\le S\le10S1 .
V (Value) Brightness: Indicates the lightness and darkness of the color. The value at the origin of the coordinates is 0, and the value at the top vertex of the cone is 1. In RGB, the color is
insert image description here
determined by three values. For example, yellow is (255,255 ,0); In HSV, yellow is only determined by one value, Hue=60.
The HSV color system can be converted to the RGB color system, and the conversion formula is as follows:

  1. RGB color system to HSV color system
    Before RGB converts to HSV color system, the three channels of R, G, and B need to be normalized to 0-1.
    V = max ( R , G , B ) V=max(R,G,B)V=max(R,G,B)
    S = { [ V − m i n ( R , G , B ) ] / V V > 0 0 V = 0 S = \begin{cases} \lbrack V-min(R,G,B)\rbrack/V & V>0 \\ 0 &V=0 \end{cases} S={ [Vmin ( R ,G,B)]/V0V>0V=0
    H = { 60 ( G − B ) / S V V = R 60 [ 2 + ( B − R ) / S V ] V = G 60 [ 4 + ( R − G ) / S V ] V = B 0 V = 0 H + 360 H < 0 H = \begin{cases} 60(G-B)/SV & V=R \\ 60\lbrack 2+(B-R)/SV\rbrack & V=G\\ 60\lbrack 4+(R-G)/SV\rbrack & V=B\\ 0 & V=0 \\ H+360 &H<0 \end{cases} H= 60(GB ) / S V60[2+(BR ) / S V ]60[4+(RG ) / S V ]0H+360V=RV=GV=BV=0H<0
  2. The formula for converting the HSV color system to the RGB color system is:
    0 < H ≤ 60 { R = VB = R − S ⋅ VG = S ⋅ V ⋅ H / 60 + B 0<H\le60 \begin{cases} R= V & \\ B=RS\cdot V \\ G=S\cdot V \\cdot H/60+B \end{cases}0<H60 R=VB=RSVG=SVH/60+B
    300 < H ≤ 360 { R = V B = R − S ⋅ V G = G − S ⋅ V ⋅ ( H − 360 ) / 60 300<H\le360 \begin{cases} R=V & \\ B=R-S\cdot V \\ G=G-S \cdot V\cdot(H-360)/60 \end{cases} 300<H360 R=VB=RSVG=GSV(H360)/60
    60 < H ≤ 120 { G = V B = G − S ⋅ V R = B − S ⋅ V ⋅ ( H − 120 ) / 60 60<H\le120 \begin{cases} G=V & \\ B=G-S\cdot V \\ R=B-S \cdot V\cdot(H-120)/60 \end{cases} 60<H120 G=VB=GSVR=BSV(H120)/60
    120 < H ≤ 180 { G = V R = G − S ⋅ V B = R + S ⋅ V ⋅ ( H − 120 ) / 60 120<H\le180 \begin{cases} G=V & \\ R=G-S\cdot V \\ B=R+S \cdot V\cdot(H-120)/60 \end{cases} 120<H180 G=VR=GSVB=R+SV(H120)/60
    180 < H ≤ 240 { B = V R = B − S ⋅ V G = R − S ⋅ V ⋅ ( H − 240 ) / 60 180<H\le240 \begin{cases} B=V & \\ R=B-S\cdot V \\ G=R-S \cdot V\cdot(H-240)/60 \end{cases} 180<H240 B=VR=BSVG=RSV(H240)/60
    240 < H ≤ 360 { B = V G = B − S ⋅ V R = G + S ⋅ V ⋅ ( H − 240 ) / 60 240<H\le360 \begin{cases} B=V & \\ G=B-S\cdot V \\ R=G+S \cdot V\cdot(H-240)/60 \end{cases} 240<H360 B=VG=BSVR=G+SV(H240)/60

Different combinations of the three colors of the RGB color space can form almost all other colors. The color is represented by a linear combination of three color components. Any color is related to these three components, and these three components are highly correlated, so it is not intuitive to change the color continuously. If you want to adjust the color of the image, you need to change it These three components will do.
However, the sensitivity of the human eye to these three color components is different. In monochrome, the human eye is the least sensitive to red and the most sensitive to blue. So the RGB color space is a color space with poor uniformity. For a certain color, it is difficult for us to speculate on the more accurate three-component numerical representation. Therefore, the RGB color space is suitable for display systems, but not suitable for image processing.
The C++ code is as follows:

cv::Mat RGB2HSV(cv::Mat img)
{
    
    
    cv::Mat hsv(img.size(), CV_32FC3);

    float r=0.0, g=0.0, b = 0.0;
    float _max = 0.0, _min = 0.0;
    float h = 0.0, s = 0.0, v = 0.0;

    for (int row = 0; row < img.rows; row++)
    {
    
    
        cv::Vec3b *currentData = img.ptr<cv::Vec3b>(row);
        for (int col = 0; col < img.cols; col++)
        {
    
    
            r = (*(currentData + col))[2] / 255;
            g = (*(currentData + col))[1] / 255;
            b = (*(currentData + col))[0] / 255;

            _max = max(r, max(g, b));
            _min = min(r, min(g, b));

            v = _max;

            if (v == 0)
            {
    
    
                s = 0;
            }
            else
            {
    
    
                s = (v - _min) / v;
            }

            if (v == r)
            {
    
    
                h = 60 * (g - b) / (s*v);
            }
            else if (v == g)
            {
    
    
                h = 60 * (2 + (b - r) / (s*v));
            }
            else if (v == b)
            {
    
    
                h = 60 * (4 + (r - g) / (s*v));
            }
            else if (v == 0)
            {
    
    
                h = 0;
            }
            else
            {
    
    
                h = h + 360;
            }
            
            hsv.at<cv::Vec3f>(row, col)[0] = h;
            hsv.at<cv::Vec3f>(row, col)[1] = s;
            hsv.at<cv::Vec3f>(row, col)[2] = v;
        }
    }
    return hsv;
}

Reference blog: https://blog.csdn.net/jinking01/article/details/120224251
https://zh.wikipedia.org/wiki/HSL%E5%92%8CHSV%E8%89%B2%E5%BD% A9%E7%A9%BA%E9%97%B4

Guess you like

Origin blog.csdn.net/qq_41596730/article/details/126939430