C++版本OpenCv教程(十)颜色模型与转换

RGB颜色模型

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

YUV颜色模型

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

HSV颜色模型

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

Lab颜色模型

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

GRAY颜色模型

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

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

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

void cv::cvtColor(InputArray src,
                  OutputArray dst,
                  int code,
                  int dstCn = 0)
  • src:待转换颜色模型的原始图像。
  • dst:转换颜色模型后的目标图像。
  • code:颜色空间转换的标志,如由RGB空间到HSV空间。常用标志及含义在表3-1中给出。
  • dstCn:目标图像中的通道数,如果参数为0,则从src和代码中自动导出通道数。

函数用于将图像从一个颜色模型转换为另一个颜色模型,前两个参数用于输入待转换图像和转换颜色空间后目标图像,第三个参数用于声明该函数具体的转换模型空间。第四个参数在一般情况下不需要特殊设置,使用默认参数即可。需要注意的是该函数变换前后的图像取值范围,由于8位无符号图像的像素由0到255,16位无符号图像的像素由0-65535,而32位浮点图像的像素是由0到1,因此一定要注意目标图像的像素范围。在线性变换的情况下,范围问题不需要考虑,目标图像的像素不会超出范围。如果在非线性变换的情况下,应将输入RGB图像归一化到适当的范围以内获得正确的结果,例如将8位无符号图像转成32位浮点图像,需要先将图像像素通过除以255缩放到0到1范围内,以防止产生错误结果。
【注意】如果转换过程中添加了alpha通道(RGB模型中第四个通道,表示透明度),则其值将设置为相应通道范围的最大值:CV_8U为255,CV_16U为65535,CV_32F为1
在这里插入图片描述
为了直观的感受同一张图像在不同颜色空间中的样子,在代码清单3-2中给出了前面几种颜色模型互相转换的程序,运行结果如图3-4所示。需要说明的是Lab颜色模型具有负数,而通过imshow()函数显示的图像无法显示负数,因此在结果中给出了Image Watch插件显示图像在Lab模型中的样子。在程序中,我们为了防止转换后出现数值越界的情况,先将CV_8U类型转成CV_32F类型后再进行颜色模型的转换。

#include<iostream>
#include<vector>
#include<string>
#include <opencv2/opencv.hpp>
#include "opencv/highgui.h"

using namespace std;
using namespace cv;

int main(int argc,char** argv) {
    cout<<"OpenCv Version: "<<CV_VERSION<<endl;
    Mat img=imread("/home/wyh/Documents/C++demo/699342568.jpg");
    if(img.empty()){
        cout<<"请确认图像文件名称是否正确"<<endl;
        return -1;
    }
    Mat dst;
    resize(img,dst,Size(img.cols*0.5,img.rows*0.5));
    Mat gray,HSV,YUV,Lab,img32;
    dst.convertTo(img32,CV_32F,1.0/255);//将CV_8U类型转换成CV_32F类型
    cvtColor(img32,HSV,COLOR_BGR2HSV);
    cvtColor(img32,YUV,COLOR_BGR2YUV);
    cvtColor(img32,Lab,COLOR_BGR2Lab);
    cvtColor(img32,gray,COLOR_BGR2GRAY);
    imshow("原图",dst);
    imshow("HSV",HSV);
    imshow("YUV",YUV);
    imshow("Lab",Lab);
    imshow("gray",gray);
    waitKey(10000);
    return 0;
}

在这里插入图片描述

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在C++中使用OpenCV YOLO,需要遵循以下步骤: 1. 下载并安装OpenCV和YOLOv3。可以从官方网站下载OpenCV,而YOLOv3可以从GitHub下载。 2. 在C++代码中加载YOLOv3模型。可以使用OpenCV的dnn模块来加载模型。以下是一个示例: ``` cv::dnn::Net net = cv::dnn::readNetFromDarknet("yolov3.cfg", "yolov3.weights"); ``` 这将创建一个包含YOLOv3模型OpenCV深度学习网络。 3. 加载图像并将其传递给YOLOv3模型进行预测。可以使用OpenCV的imread函数加载图像,并使用cv::dnn::blobFromImage函数将其转换模型所需的格式。以下是一个示例: ``` cv::Mat image = cv::imread("image.jpg"); cv::Mat blob = cv::dnn::blobFromImage(image, 1/255.0, cv::Size(416, 416), cv::Scalar(0,0,0), true, false); net.setInput(blob); cv::Mat detection = net.forward(); ``` 这将加载图像,将其转换模型所需的格式,将其传递给模型进行预测,并返回检测结果。 4. 处理检测结果并在图像上绘制边界框。可以使用OpenCV的Mat类来处理检测结果,并使用cv::rectangle函数在图像上绘制边界框。以下是一个示例: ``` for (int i = 0; i < detection.rows; ++i) { float confidence = detection.at<float>(i, 4); if (confidence > 0.5) { int x1 = static_cast<int>(detection.at<float>(i, 0) * image.cols); int y1 = static_cast<int>(detection.at<float>(i, 1) * image.rows); int x2 = static_cast<int>(detection.at<float>(i, 2) * image.cols); int y2 = static_cast<int>(detection.at<float>(i, 3) * image.rows); cv::rectangle(image, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(0, 255, 0), 2); } } ``` 这将遍历检测结果,筛选出置信度大于0.5的检测结果,并在图像上绘制边界框。 这样,就可以在C++中使用OpenCV YOLO进行目标检测了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值