【计算机视觉1】–图形预处理(色彩空间转换)

  • Post author:
  • Post category:其他




图像预处理

计算机视觉图像预处理是指在进行图像处理前对图像进行一系列的处理和转换,以便更好地进行后续的图像处理和分析。其主要目的是使得图像能够被计算机识别、处理和分析,同时保留尽可能多的有用信息。

图像预处理框架图

今天主要讲下色彩空间转换,其他的在

图像增强算法



锐化算法

中都有提到。



色彩空间转换

色彩空间转换是指将图像的表示方式从一个色彩空间转换为另一个色彩空间的过程。常见的色彩空间包括RGB、HSV、CMYK等。下面是几种常见的色彩空间转换方法:



RGB到HSV的转换

RGB色彩空间包含红、绿、蓝三个分量,而HSV色彩空间包含色调(Hue)、饱和度(Saturation)和值(Value)三个分量。转换方法如下:

  • 计算最大值和最小值:max_val = max(R, G, B),min_val = min(R, G, B)。
  • 计算色调(Hue):
		如果max_val = min_val,则Hue = 0(定义为红色)
		如果max_val = R,则Hue = (G - B) / (max_val - min_val)
		如果max_val = G,则Hue = 2 + (B - R) / (max_val - min_val)
		如果max_val = B,则Hue = 4 + (R - G) / (max_val - min_val)
  • 计算饱和度(Saturation):
	如果max_val = 0,则Saturation = 0
	否则,Saturation = (max_val - min_val) / max_val
  • 计算值(Value):Value = max_val

  • Python实现

def rgb_to_hsv(r, g, b):
    r, g, b = r / 255.0, g / 255.0, b / 255.0
    max_val = max(r, g, b)
    min_val = min(r, g, b)
    hue, saturation, value = 0, 0, 0

    # 计算色调
    if max_val == min_val:
        hue = 0
    elif max_val == r:
        hue = 60 * (0 + (g - b) / (max_val - min_val))
    elif max_val == g:
        hue = 60 * (2 + (b - r) / (max_val - min_val))
    elif max_val == b:
        hue = 60 * (4 + (r - g) / (max_val - min_val))

    # 计算饱和度
    if max_val != 0:
        saturation = (max_val - min_val) / max_val

    # 计算值
    value = max_val
  • C++实现
void RGBtoHSV(int r, int g, int b, double& h, double& s, double& v) {
    double red = r / 255.0;
    double green = g / 255.0;
    double blue = b / 255.0;

    double maxVal = std::max({ red, green, blue });
    double minVal = std::min({ red, green, blue });
    double delta = maxVal - minVal;

    // 计算色调 (Hue)
    if (delta == 0) {
        h = 0;  // 无色彩,色调为0
    }
    else if (maxVal == red) {
        h = 60 * ((green - blue) / delta);
    }
    else if (maxVal == green) {
        h = 60 * ((blue - red) / delta + 2);
    }
    else if (maxVal == blue) {
        h = 60 * ((red - green) / delta + 4);
    }

    if (h < 0) {
        h += 360;  // 调整为0到360度之间
    }

    // 计算饱和度 (Saturation)
    if (maxVal == 0) {
        s = 0;
    }
    else {
        s = delta / maxVal;
    }

    // 计算值 (Value)
    v = maxVal;
}



HSV到RGB的转换

HSV色彩空间中的色调(Hue)、饱和度(Saturation)和值(Value)可以转换为RGB色彩空间中的红、绿、蓝分量。转换方法如下:

  • 如果Saturation = 0,则R = G = B = Value
  • 否则,根据Hue的值计算对应的区间,并进行相应的计算:
	将Hue乘以6得到一个角度值,记为H
	将H向下取整得到一个整数部分,记为I
	计算H减去I后的小数部分,记为F
	计算P = Value × (1 - Saturation)
	计算Q = Value × (1 - Saturation × F)
	计算T = Value × (1 - Saturation × (1 - F))
	根据I的值选择相应的计算公式计算R、G、B的值:
		如果I = 0,则R = Value,G = T,B = P
		如果I = 1,则R = Q,G = Value,B = P
		如果I = 2,则R = P,G = Value,B = T
		如果I = 3,则R = P,G = Q,B = Value
		如果I = 4,则R = T,G = P,B = Value
		如果I = 5,则R = Value,G = P,B = Q
  • Python实现
def hsv_to_rgb(h, s, v):
    if s == 0:
        r = g = b = v
    else:
        h /= 60
        i = int(h)
        f = h - i
        p = v * (1 - s)
        q = v * (1 - s * f)
        t = v * (1 - s * (1 - f))

        if i == 0:
            r, g, b = v, t, p
        elif i == 1:
            r, g, b = q, v, p
        elif i == 2:
            r, g, b = p, v, t
        elif i == 3:
            r, g, b = p, q, v
        elif i == 4:
            r, g, b = t, p, v
        else:
            r, g, b = v, p, q
  • C++实现
void HSVtoRGB(double h, double s, double v, int& r, int& g, int& b) {
    if (s == 0) {
        r = g = b = v * 255;
        return;
    }

    h /= 60;
    int i = static_cast<int>(h);
    double f = h - i;
    double p = v * (1 - s);
    double q = v * (1 - s * f);
    double t = v * (1 - s * (1 - f));

    switch (i) {
        case 0:
            r = static_cast<int>(v * 255);
            g = static_cast<int>(t * 255);
            b = static_cast<int>(p * 255);
            break;
        case 1:
            r = static_cast<int>(q * 255);
            g = static_cast<int>(v * 255);
            b = static_cast<int>(p * 255);
            break;
        case 2:
            r = static_cast<int>(p * 255);
            g = static_cast<int>(v * 255);
            b = static_cast<int>(t * 255);
            break;
        case 3:
            r = static_cast<int>(p * 255);
            g = static_cast<int>(q * 255);
            b = static_cast<int>(v * 255);
            break;
        case 4:
            r = static_cast<int>(t * 255);
            g = static_cast<int>(p * 255);
            b = static_cast<int>(v * 255);
            break;
        default:
            r = static_cast<int>(v * 255);
            g = static_cast<int>(p * 255);
            b = static_cast<int>(q * 255);
            break;
    }
}

请注意,色调应该在0到360之间,饱和度和值应该在0到1之间。返回的RGB值将在0到255之间。



RGB到CMYK的转换

RGB色彩空间中的红、绿、蓝分量可以转换为CMYK色彩空间中的青、黄、洋红、黑分量。转换方法如下:

  • 计算Cyan:Cyan = 1 – (Red / 255)
  • 计算Magenta:Magenta = 1 – (Green / 255)
  • 计算Yellow:Yellow = 1 – (Blue / 255)
  • 计算Black:Black = min(Cyan, Magenta, Yellow)
  • Python实现
def rgb_to_cmyk(r, g, b):
    r, g, b = r / 255.0, g / 255.0, b / 255.0

    k = 1 - max(r, g, b)
    if k == 1:
        return 0, 0, 0, 1

    c = (1 - r - k) / (1 - k)
    m = (1 - g - k) / (1 - k)
    y = (1 - b - k) / (1 - k)
  • C++实现
void RGBtoCMYK(int r, int g, int b, double& c, double& m, double& y, double& k) {
    double red = r / 255.0;
    double green = g / 255.0;
    double blue = b / 255.0;

    double maxVal = std::max({ red, green, blue });

    // 计算黑色分量 (Black)
    k = 1 - maxVal;

    // 避免除以0的情况
    if (k == 1) {
        c = m = y = 0;
    }
    else {
        // 计算青色分量 (Cyan)
        c = (1 - red - k) / (1 - k);
        // 计算洋红分量 (Magenta)
        m = (1 - green - k) / (1 - k);
        // 计算黄色分量 (Yellow)
        y = (1 - blue - k) / (1 - k);
    }
}

返回的CMYK分量将在0到1之间,其中0表示没有该颜色分量,1表示最大值(黑色)。请注意,对于黑色分量,值为1表示纯黑色。

以上都是常用的色彩空间转换方法,可以根据项目需求采取适合的转换方法来实现图像色彩空间的转换。



版权声明:本文为weixin_43504942原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。