首页 > 其他分享 >Opencv学习-图像颜色空间

Opencv学习-图像颜色空间

时间:2024-08-07 14:57:38浏览次数:11  
标签:颜色 模型 Opencv RGB 图像 转换 通道

        通过红、绿、蓝 3 种颜色不同比例的混合能够让图像展现出五彩斑斓的颜色,这种模型称为 RGB 颜色模型。 RGB 颜色模型是最常见的颜色模型之一,常用于表示和显示图像。为了能够表 示 3 种颜色的混合,图像以多通道的形式分别存储某一种颜色的红色分量、绿色分量和蓝色分量。 除 RGB 颜色模型外,图像的颜色模型还有 YUV 、 HSV 等模型,分别表示图像的亮度、色度、饱 和度等分量。了解图像颜色空间对分割拥有颜色区分特征的图像具有重要的帮助,例如提取图像中 的红色物体可以通过比较图像红色通道的像素值来实现。

1.  颜色模型与转换

       OpenCV 4 中能够互相转换的常见颜色模型,例如 RGB 模型、 HSV 模型、Lab 模型、 YUV 模型及 GRAY 模型,并介绍这几种模型之间的数学转换关系、 OpenCV 4 中提供的这几种模型之间的变换函数。

1.1 RGB 颜色模型

        前面对于 RGB 颜色模型已经有所介绍,该模型的命名方式是采用 3 种颜色的英文首字母,分 别是红色( Red )、绿色( Green )和蓝色( Blue )。虽然该颜色模型的命名方式是红色在前,但是在 OpenCV 中却是相反的顺序,第一个通道是蓝色( B )分量,第二个通道是绿色( G )分量,第三个通道是红色(R )分量。根据存储顺序的不同, OpenCV 4 中提供了这种顺序的反序格式,用于 存储第一个通道是红色分量的图像,但是这两种格式图像的颜色空间是相同的,颜色空间模型如下图 所示。 3 个通道对于颜色描述的范围是相同的,因此 RGB 颜色模型的空间构成是一个立方体。在 RGB 颜色模型中,所有的颜色都是由这 3 种颜色通过不同比例的混合得到,如果 3 种颜色分量都为 0 ,则表示为黑色,如果 3 种颜色的分量相同且都为最大值,则表示为白色。每个通道都表示某一种颜色 0 ~ 1 的过程,不同位数的图像表示将这个颜色变化过程细分成不同的层级,例如8UC3 格式的图像每个通道将这个过程量化成 256 个等级,分别由 0 ~ 255 表示。在这个模型的基础上增加第四个通道即为 RGBA 模型,第四个通道表示颜色的透明度,当没有透明度需求的时候, RGBA 模型就会退化成 RGB 模型。

RGB 颜色空间模型  

1.2 YUV 颜色模型  

        YUV 模型是电视信号系统所采用的颜色编码方式。这 3 个变量分别表示像素的亮度( Y )、红色分量与亮度的信号差值(U )、蓝色与亮度的差值( V )。这种颜色模型主要用于视频和图像的传输,该模型的产生与电视机的发展历程密切相关。由于彩色电视机在黑白电视机发明之后才产生,因此用于彩色电视机的视频信号需要能够兼容黑白电视机。彩色电视机需要 3 个通道的数据才能显示彩色,而黑白电视机只需要一个通道的数据,因此,为了使视频信号能够兼容彩色电视机与黑白电视机,将 RGB 编码方式转变成 YUV 的编码方式,其 Y 通道是图像的亮度,黑白电视只需要使用该通道就可以显示黑白视频图像,而彩色电视机通过将 YUV 编码转成 RGB 编码方式,便可以在彩色电视机中显示彩色图像,较好地解决了同一个视频信号兼容不同类型电视机的问题。RGB模型与 YUV 模型之间的转换关系如图 所示,其中 RGB 取值范围均为 0 ~ 255 。

1.3 HSV 颜色模型  

        HSV 是色度( Hue )、饱和度( Saturation )和亮度( Value )的简写,通过名字也可以看出该模型通过这 3 个特性对颜色进行描述。色度是色彩的基本属性,就是平时常说的颜色,例如红色、蓝色等;饱和度是指颜色的纯度,饱和度越高色彩越纯和越艳,饱和度越低,色彩则逐渐地变灰和变暗,饱和度的取值范围是 0 ~ 100% ;亮度是颜色的明亮程度,其取值范围由 0 到计算机中允许的最大值。由于色度、饱和度和亮度的取值范围不同,因此其颜色空间模型用锥形表示,如下图 所示。相比于 RGB 模型 3 个颜色分量与最终颜色联系不直观的缺点, HSV 模型更加符合人类感知颜色的方式:颜色、深浅及亮暗。

HSV 颜色空间模型  

1.4 Lab 颜色模型

        Lab 颜色模型弥补了 RGB 模型的不足,是一种设备无关和基于生理特征的颜色模型。在模型 中, L 表示亮度( Luminosity ), a 和 b 是两个颜色通道,两者的取值区间都是 −128 ~ 127 ,其中 a通道数值由小到大对应的颜色是从绿色变成红色,b 通道数值由小到大对应的颜色是由蓝色变成黄色。Lab 颜色模型构成的颜色空间是一个球形。

Lab 颜色空间模型  

1.5 GRAY 颜色模型

        GRAY 模型并不是一个彩色模型,而是一个灰度图像的模型,其命名使用的是英文单词 gray 的全字母大写。灰度图像只有单通道,灰度值根据图像位数不同由 0 到最大依次表示由黑到白,例 如 8UC1 格式中,由黑到白被量化为 256 个等级,通过 0 ~ 255 表示,其中 255 表示白色。彩色图像具有颜色丰富、信息含量大的特性,但是灰度图在图像处理中依然具有一定的优势。例如,灰度图像具有相同尺寸相同压缩格式所占容量小、易于采集、便于传输等优点。常用的 RGB 模型转成 灰度图的方式如下图 所示。

2. 不同颜色模型间的互相转换

针对图像不同颜色模型之间的相互转换, OpenCV 4 提供了 cvtColor() 函数用于实现转换功能。

2.1  cvtColor()函数原型

void cv::cvtColor(InputArray src, 
OutputArray dst, 
int code, 
int dstCn = 0 
)
• src :待转换颜色模型的原始图像。 • dst :转换颜色模型后的目标图像。 • code :颜色模型转换标志,如由 RGB 空间到 HSV 空间 。 • dstCn :目标图像中的通道数。如果参数为 0 ,则从 src 和代码中自动导出通道数。
        函数用于将图像从一个颜色模型转换为另一个颜色模型,前两个参数用于输入待转换图像和转换颜色空间后的目标图像,第三个参数用于声明该函数具体的转换模型空间,常用的标志在下表中给出, 第四个参数在一般情况下不需要特殊设置,使用默认参数即可。需要注意的是该函数变换前后的图像取值范围,由于 8 位无符号图像的像素为 0 ~ 255 , 16 位无符号图像的像素为 0 ~ 65 535 ,而 32 位浮点图像的像素为 0 ~ 1 ,因此一定要注意目标图像的像素范围。在线性变换的情况下,范围问题不需要考虑,目标图像的像素不会超出范围。如果在非线性变换的情况下,那么应将输入 RGB 图像归一化到适当的范围以内来获得正确的结果,例如将 8 位无符号图像转成 32 位浮点图像,需要先将图像像素通过除以 255 缩放到 0 ~ 1 范围内,以防止产生错误结果。 颜色模型转换常用标志

        程序中需要说明的是,Lab 颜色模型具有负数,而通过 imshow()函数显示的图像无法显示负数,因此在结果中给出了利用 Image Watch 插件显示图像在 Lab模型中的样子。在程序中,为了防止转换后出现数值越界的情况,我们先将CV_8U 类型转成 CV_32F类型后再进行颜色模型的转换。

2.2 示例代码

#include <opencv2/opencv.hpp> 
#include <iostream> 
#include <vector> 

using namespace std; 
using namespace cv; 

int main() 
{ 
    Mat img = imread("../pic/gril_1.jpg"); 
    if (img.empty()) 
    { 
        cout << "请确认图像文件名称是否正确" << endl; 
        return -1; 
    } 
    Mat gray, HSV, YUV, Lab, img32; 
    img.convertTo(img32, CV_32F, 1.0 / 255); //将 CV_8U 类型转换成 CV_32F 类型
    //img32.convertTo(img, CV_8U, 255); //将 CV_32F 类型转换成 CV_8U 类型
    cvtColor(img32, HSV, COLOR_BGR2HSV); 
    cvtColor(img32, YUV, COLOR_BGR2YUV); 
    cvtColor(img32, Lab, COLOR_BGR2Lab); 
    cvtColor(img32, gray, COLOR_BGR2GRAY); 
    imshow("原图", img32); 
    imshow("HSV", HSV);
    imshow("YUV", YUV); 
    imshow("Lab", Lab); 
    imshow("gray", gray); 
    waitKey(0); 
    return 0; 
}

2.3 运行结果

2.3 convertTo()函数原型

void cv::Mat::convertTo(OutputArry m, 
int rtype, 
double alpha = 1, 
double beta = 0 
)
• m :转换类型后输出的图像。 • rtype :转换图像的数据类型。 • alpha :转换过程中的缩放因子。 • beta :转换过程中的偏置因子。

        该函数用来实现将已有图像转换成指定数据类型的图像,第一个参数用于输出转换数据类型后的图像,第二个参数用于声明转换后图像的数据类型。第三个参数与第四个参数用于声明两个数据类型间的转换关系,具体转换形式如下图所示。

        通过转换公式可以知道,该转换方式就是将原有数据进行线性转换,并按照指定的数据类型输 出。根据其转换规则可以知道,该函数不但能够实现不同数据类型之间的转换,而且能够实现在同 一种数据类型中的线性变换。我们在示例代码 中给出了 CV_8U 类型和 CV_32F 类型之间互相转换的示例。

2.4  saturate_cast函数简单介绍

 saturate_cast<uchar>主要是为了防止颜色溢出操作(0~255)
if(data<0)
        data=0;
else if(data>255)
        data=255; else         data不变;
int a ,b ,c, d,f,e;
a = 100;
b = 200; 
c = -200;
d =  saturate_cast<uchar>(a + b);
f =  saturate_cast<uchar>(c);
e =  saturate_cast<uchar>(a);
cout << " d == " << d << "  f == " << f  <<"  e == " << e <<  endl;

 运行结果:

3. 多通道分离与合并  

        在图像颜色模型中,不同的分量存放在不同的通道中,如果我们只需要颜色模型的某一个分量,例如只需要处理 RGB 图像中的红色通道,那么可以将红色通道从 3 个通道的数据中分离出来再进行处理,这种方式可以减少数据所占据的内存,加快程序的运行速度。同时,当我们分别处理完多个通道后,需要将所有通道合并在一起重新生成 RGB 图像。针对图像多通道的分离与混合, OpenCV 4 中提供了 split() 函数和 merge() 函数用于满足这些需求。

3.1 split()函数原型

void cv::split(const Mat & src, Mat * mvbegin ) 
void cv::split(InputArray m, OutputArrayOfArrays mv )
  • src:待分离的多通道图像。
  • mvbegin:分离后的单通道图像,为数组形式,数组大小需要与图像的通道数相同。
  • m:待分离的多通道图像。
  • mv:分离后的单通道图像,为向量(vector)形式。

        ​​该函数主要是用于将多通道的图像分离成若干单通道的图像,两个函数原型中不同之处在于, 前者第二个参数输出的是 Mat 类型的数组,其数组的长度需要与多通道图像的通道数相等并且提前 定义;第二种函数原型的第二个参数输出的是一个 vector<Mat>容器,不需要知道多通道图像的通道数。

3.2 多通道合并函数 merge()

void merge(const Mat* mv, size_t count, OutputArray dst);
void merge(const vector& mv, OutputArray dst );

mv(第一种重载原型参数):需要合并的图像数组,其中每个图像必须拥有相同的尺寸和数据类型。
count:输入的图像数组的长度,其数值必须大于 0。
mv(第二种重载原型参数):需要合并的图像向量(vector),其中每个图像必须拥有相同的尺寸和数据类型。
dst:合并后输出的图像,与 mv[0]具有相同的尺寸和数据类型,通道数等于所有输入图像的通道数总和。

        该函数主要用于将多个图像合并成一个多通道图像,该函数也具有两种不同的函数原型,每一种函数原型都与 split() 函数相对应,两种原型分别输入数组形式的图像数据和向量( vector )形式的图像数据,在输入数组形式数据的原型中,还需要输入数组的长度。合并函数的输出结果是一个多通道的图像,其通道数目是所有输入图像通道数目的总和。这里需要说明的是,用于合并的图像并非都是单通道的,也可以是多个通道数目不相同的图像合并成一个通道更多的图像。虽然这些图像的通道数目可以不相同,但是需要所有图像具有相同的尺寸和数据类型。

3.3 示例代码

#include <opencv2/opencv.hpp> 
#include <iostream> 
#include <vector> 
 
using namespace std; 
using namespace cv; 
 
int main() 
{ 
    Mat img = imread("../pic/hand.jpg"); 
    if (img.empty()) 
    { 
        cout << "请确认图像文件名称是否正确" << endl; 
        return -1; 
    } 
    Mat HSV; 
    cvtColor(img, HSV, COLOR_RGB2HSV); 
    Mat imgs0, imgs1, imgs2; //用于存放数组类型的结果
    Mat imgv0, imgv1, imgv2; //用于存放 vector 类型的结果
    Mat result0, result1, result2; //多通道合并的结果
    
    //输入数组参数的多通道分离与合并
    Mat imgs[3]; 
    split(img, imgs); 
    imgs0 = imgs[0]; 
    imgs1 = imgs[1]; 
    imgs2 = imgs[2]; 
    // imshow("RGB-B 通道", imgs0); //显示分离后 B 通道的像素值
    // imshow("RGB-G 通道", imgs1); //显示分离后 G 通道的像素值
    // imshow("RGB-R 通道", imgs2); //显示分离后 R 通道的像素值
    //imgs[2] = img; //将数组中的图像通道数变成不一致
    merge(imgs, 3, result0); //合并图像
    imshow("result0", result0); //imshow 最多显示 4 个通道,因此结果在 Image Watch 中查看
    Mat zero = cv::Mat::zeros(img.rows, img.cols, CV_8UC1); 
    imgs[0] = zero; 
    imgs[2] = zero; 
    merge(imgs, 3, result1); //用于还原 G 通道的真实情况,合并结果为绿色
    imshow("result1", result1); //显示合并结果
    
    //输入 vector 参数的多通道分离与合并
    vector<Mat> imgv; 
    split(img, imgv); 
    // imgv0 = imgv.at(0); 
    // imgv1 = imgv.at(1); 
    // imgv2 = imgv.at(2); 
    // imshow("HSV-H 通道", imgv0); //显示分离后 H 通道的像素值
    // imshow("HSV-S 通道", imgv1); //显示分离后 S 通道的像素值
    // imshow("HSV-V 通道", imgv2); //显示分离后 V 通道的像素值
    //imgv.push_back(HSV); //将 vector 中的图像通道数变成不一致
    merge(imgv, result2); //合并图像
    imshow("result2", result2); //imshow 最多显示 4 个通道,因此结果在 Image Watch 中查看
    waitKey(0); 
    return 0; 
}

3.4 运行结果

 

 

标签:颜色,模型,Opencv,RGB,图像,转换,通道
From: https://blog.csdn.net/m0_63893772/article/details/140986851

相关文章

  • (全网最详细的可运行的人流统计程序)基于OpenCV的实时视频处理系统
    OpenCV人脸检测OpenCV提供了多种人脸检测方法,包括基于Haar级联的传统方法和基于深度学习的现代方法。Haar级联是一种经典的机器学习算法,适用于实时应用,因为它可以快速处理图像。级联(Cascade)结构:Cascade分类器由多个简单的分类器组成,这些分类器按照一定的顺序级联起来。每个......
  • 深入解析:人工智能视觉利器OpenCV的技术奥秘
    人工智能视觉利器OpenCV的技术奥秘1.图像处理基础1.1数字图像基础知识1.1.1像素1.1.2色彩空间1.2图像处理中的常见任务1.2.1图像分割1.2.2图像识别1.2.3图像检测1.3颜色检测与图像处理的结合2.OpenCV简介2.1OpenCV的历史和发展早期发展持续演进开源社区的......
  • 图像文字报表
    概述图像文字报表:报表中混合显示文字与图像,实现图像与文字的混合排列。应用场景如下图所示,简单展示数据示例说明数据准备在数据面板中添加数据集,可选择Json数据集和API服务数据集。Json数据集输入如下图所示:[{"图像":"https://img0.baidu.com/it/u=3609521783,32494......
  • 图像识别与处理之Opencv——Mat_类与Mat 类的内存管理
    Mat_类Mat_类是对Mat类的一个包装,其定义如下点击查看代码template<typename_Tp>classMat_:publicMat{public://只定义了几个方法//没有定义新的属性};这是一个非常轻量级的包装,既然已经有Mat类,为何还要定义一个Mat_类?下面我们看这段代码:点击查看代码Ma......
  • HSSFColor.HSSFColorPredefined 颜色分类
    原文:https://blog.csdn.net/shanghaojiabohetang/article/details/51837242   ......
  • pytorch实现神经网络图像分类
    Tensor在PyTorch中,最核心的数据结构就是Tensor了,可以认为Tensor与Numpy中的ndarrays非常类似,但是Tensor可以使用GPU加速而ndarrays不可以。在pytorch进行GPU运算iftorch.cuda.is_available():x=x.cuda()y=y.cuda()print(x+y)numpy与pytorch互相转换importtorch......
  • Excel 根据单元格值设置行颜色
     开始》条件格式》管理规则》新建格式规则》使用公式确定要设置格式的单元格只为满足以下条件的单元格设置格式:=SEARCH("进行中",$E5)>0;(注释:此处筛选的是包含进行中的数据)格式:选择满足条件的单元格设置什么格式 应用于:选择此行需要改颜色格式的单元格  对某个单元格......
  • 采购订单打开单据时表格行设置颜色
     列表根据条件设置背景色importclrclr.AddReference('System')clr.AddReference('Kingdee.BOS')clr.AddReference('Kingdee.BOS.Core')clr.AddReference('System.Drawing')clr.AddReference('System.Collections')fromS......
  • 高速图像采集卡设计原理图: 613-基于6UVPX C6678+XCVU9P的信号处理板卡
    基于6UVPXC6678+XCVU9P的信号处理板卡一、板卡概述      板卡基于6U VPX标准结构,包含一个C6678 DSP芯片,一个XCVU9P 高性能FPGA,双路HPC FMC。  二、处理板技术指标•  DSP处理器采用TI 8核处理器TMS320C6678;•  DSP 外挂一组64bit DDR3......
  • 图像风格迁移技术(论文复现)
    图像风格迁移技术(论文复现)本文所涉及所有资源均在传知代码平台可获取文章目录图像风格迁移技术(论文复现)概述内容&风格表示内容风格演示效果核心逻辑使用方式概述图像风格迁移是指将一张图像的内容与另一张图像的风格相融合,生成具有新风格的图像。风格......