图像处理之HSV颜色空间

目录

[1 RGB 的局限性](#1 RGB 的局限性)

[2 HSV 颜色空间](#2 HSV 颜色空间)

[3 RGB与HSV相互转换](#3 RGB与HSV相互转换)

[4 HSV颜色模型对图像的色相、饱和度和明度进行调节](#4 HSV颜色模型对图像的色相、饱和度和明度进行调节)

[5 演示Demo](#5 演示Demo)

[5.1 开发环境](#5.1 开发环境)

[5.2 功能介绍](#5.2 功能介绍)

[5.3 下载地址](#5.3 下载地址)

参考


1 RGB 的局限性

RGB 是我们接触最多的颜色空间,由三个通道表示一幅图像,分别为红色(R),绿色(G)和蓝色(B)。这三种颜色的不同组合可以形成几乎所有的其他颜色。

RGB 颜色空间是图像处理中最基本、最常用、面向硬件的颜色空间,比较容易理解。

RGB 颜色空间利用三个颜色分量的线性组合来表示颜色,任何颜色都与这三个分量有关,而且这三个分量是高度相关的,所以连续变换颜色时并不直观,想对图像的颜色进行调整需要更改这三个分量才行。

自然环境下获取的图像容易受自然光照、遮挡和阴影等情况的影响,即对亮度比较敏感。而 RGB 颜色空间的三个分量都与亮度密切相关,即只要亮度改变,三个分量都会随之相应地改变,而没有一种更直观的方式来表达

但是人眼对于这三种颜色分量的敏感程度是不一样的,在单色中,人眼对红色最不敏感,蓝色最敏感,所以 RGB 颜色空间是一种均匀性较差的颜色空间。如果颜色的相似性直接用欧氏距离来度量,其结果与人眼视觉会有较大的偏差。对于某一种颜色,我们很难推测出较为精确的三个分量数值来表示。所以,RGB 颜色空间适合于显示系统,却并不适合于图像处理。

2 HSV 颜色空间

基于上述理由,在图像处理中使用较多的是 HSV 颜色空间,它比 RGB 更接近人们对彩色的感知经验。非常直观地表达颜色的色调、鲜艳程度和明暗程度,方便进行颜色的对比。

在 HSV 颜色空间下,比 RGB 更容易跟踪某种颜色的物体,常用于分割指定颜色的物体。

HSV 表达彩色图像的方式由三个部分组成:

  • Hue(色调、色相),相当于基调,是下图的俯视图得到的圆,圆上不同位置的颜色基调不同,把颜色分成了360°,每个位置有不同的颜色基调;

  • Saturation(饱和度、色彩纯净度):纯度,沿着俯视图得到的圆的半径看,因为圆弧上的点代表该处的颜色的基调,那么半径上就是从纯白色到该基调颜色过渡过程中不同位置的纯度,在圆心处纯度为0,在圆弧上(该色调)纯度为100;

  • Value(明度):亮度,沿着圆柱的高来看,圆柱表面上平行于圆柱轴上的点的颜色基调相同,纯度也相同,但是明暗程度不同。同时,该圆柱的半径也不同,相当于磁盘的柱面。

用下面这个圆柱体来表示 HSV 颜色空间,圆柱体的横截面可以看做是一个极坐标系 ,H 用极坐标的极角表示,S 用极坐标的极轴长度表示,V 用圆柱中轴的高度表示。

  • 色相H:表示色彩信息,即所处的光谱颜色的位置。该参数用一角度量来表示,取值范围为0°~360°。其中0°为红色,60°为黄色,120°为绿色,180°为青色,240°为蓝色,300°为紫色。

  • 饱和度S:表示色彩的纯度,取值范围为0.0~1.0。值越大,纯度越高,接近光谱色的程度也就越高,图像越鲜艳。

  • 明度V:表示色彩的明亮程度,取值范围为0.0(黑色)~1.0(白色)。明度越高,色彩越亮。

3 RGB HSV 相互转换

了解了HSV的颜色特性之后,就可以在实际使用中RGB颜色值转换为HSV颜色值,然后对色相、饱和度和明度进行调整。达到效果需求之后,再转换为RGB值显示在屏幕上保存结果。

下面使用C语言编程实现RGB与HSV的转换

cpp 复制代码
#include"TRGB2HSV.h"
#include"Commen.h"
#include<stdlib.h>
#include<math.h>

void RGB2HSV(unsigned char R, unsigned char G, unsigned char B, float* h, float* s, float * v)
{
    float min, max;
    float r = R / 255.0;
    float g = G / 255.0;
    float b = B / 255.0;
    min = MIN2(r,MIN2(g,b));
    max = MAX2(r,MAX2(g,b));
    if (max == min)
        *h = 0;
    else if (max == r && g >= b)
        *h = 60.0 * (g - b) / (max - min);
    else if (max == r && g < b)
        *h = 60.0 * (g - b) / (max - min) + 360.0;
    else if (max == g)
        *h = 60.0 * (b - r) / (max - min) + 120.0;
    else if (max == b)
        *h = 60.0 * (r - g) / (max - min) + 240.0; 
        *h = CLIP3(*h, 0, 360);
    if (max == 0)
        *s = 0;
    else
        *s = (max - min) / max;
    *v = max;
};

void HSV2RGB(float h, float s, float v, unsigned char* R, unsigned char *G, unsigned char *B)
{
    float q = 0, p = 0, t = 0, f = 0, r = 0, g = 0, b = 0;
    int hN = 0;
    if(h == 360)
        h = 0;
    if (h < 0)
        h = 360 + h;
    hN = (int)((int)h / 60);
    f = h / 60.0f - hN;
    p = v * (1.0 - s);
    q = v * (1.0 - f * s);
    t = v * (1.0 - (1.0 - f) * s);
    switch (hN)
    {
    case 0:
        r = v;
        g = t;
        b = p;
        break;
    case 1:
        r = q;
        g = v;
        b = p;
        break;
    case 2:
        r = p;
        g = v;
        b = t;
        break;
    case 3:
        r = p;
        g = q;
        b = v;
        break;
    case 4:
        r = t;
        g = p;
        b = v;
        break;
    case 5:
        r = v;
        g = p;
        b = q;
        break;
    default:
        break;
    }
    *R = (unsigned char)CLIP3((r * 255.0),0,255);
    *G = (unsigned char)CLIP3((g * 255.0),0,255);
    *B = (unsigned char)CLIP3((b * 255.0),0,255);
};

4 HSV颜色模型对图像的色相、饱和度和明度进行调节

cpp 复制代码
/*************************************************
功    能:HSV调整
参    数:srcData     - [输入/输出] 原始图像,格式为32位BGRA格式,执行后修为结果图像
         width       - [输入] 原始图像宽度
         height      - [输入] 原始图像高度
         tride       - [输入] 原始图像的Stride(也就是行字节数width*4)
         hIntensity  - [输入] h值
         sIntensity  - [输入] s值
         vIntensity  - [输入] v值
返    回: 0-成功, 其他-失败.
*************************************************/
int adjustHSV(unsigned char *srcData, int width, int height, int stride, float hIntensity, float sIntensity, float vIntensity)
{
    int ret = 0;
    if (srcData == NULL)
    {
        printf("input image is null!");
        return -1;
    }
    //Process
    unsigned char R, G, B;
    float h = 0, s = 0, v = 0;
    unsigned char* pSrc = srcData;
    int offset = stride - width * 4;
    for (int j = 0; j < height; j++)
    {
        for (int i = 0; i < width; i++)
        {
            B = pSrc[0];
            G = pSrc[1];
            R = pSrc[2];
            RGB2HSV(R, G, B, &h, &s, &v);
            h = h + hIntensity > 360 ? h + hIntensity - 360 : h + hIntensity;
            s = CLIP3(s + sIntensity, 0, 1.0f);
            v = CLIP3(v + vIntensity, 0, 1.0f);
            HSV2RGB(h, s, v, &R, &G, &B);
            pSrc[0] = B;
            pSrc[1] = G;
            pSrc[2] = R;
            pSrc += 4;
        }
        pSrc += offset;
    }
    return ret;
};

5 演示Demo

5.1 开发环境

  • Windows 10 Pro x64

  • Visual Studio 2015

5.2 功能介绍

演示程序主界面如下图所示,具有图像读取、显示、保存、显示RGBA值,以及HSV调整、鼠标按键按下显示原图、鼠标按键抬起显示效果图等功能。

原图

效果图(h=26, s=0.12, v=0.16)

5.3 下载地址

开发环境:

  • Windows 10 pro x64

  • Visual Studio 2015

下载地址: 图像处理之HSV颜色空间

参考

图像视频滤镜与人像美颜美妆算法详解. 胡耀武、谭娟、李云夕. 电子工业出版社、2020-07

相关推荐
七芒星202319 小时前
多目标识别YOLO :YOLOV3 原理
图像处理·人工智能·yolo·计算机视觉·目标跟踪·分类·聚类
2401_841495643 天前
【计算机视觉】分水岭实现医学诊断
图像处理·人工智能·python·算法·计算机视觉·分水岭算法·医学ct图像分割
格林威3 天前
常规可见光相机在工业视觉检测中的应用
图像处理·人工智能·数码相机·计算机视觉·视觉检测
扶尔魔ocy3 天前
【QT常用技术讲解】multimedia实现指定分辨率打开摄像头
图像处理·qt
格林威3 天前
工业视觉检测里的 “柔性” 是什么?
图像处理·人工智能·深度学习·yolo·计算机视觉·视觉检测
格林威3 天前
不同光谱的工业相机有哪些?能做什么?
图像处理·人工智能·深度学习·数码相机·计算机视觉·视觉检测
CiLerLinux3 天前
第三十八章 ESP32S3 SPIFFS 实验
图像处理·人工智能·单片机·嵌入式硬件
要做朋鱼燕4 天前
【OpenCV】图像处理入门:从基础到实战技巧
图像处理·人工智能·opencv
不枯石4 天前
Matlab通过GUI实现点云的随机一致性(RANSAC)配准
开发语言·图像处理·算法·计算机视觉·matlab
那雨倾城4 天前
PiscCode:基于OpenCV的前景物体检测
图像处理·python·opencv·计算机视觉