opencv3学习笔记(三)RGB HSV YUV相互转换

一.知识点
1.RGB模式
RGB模式是基于自然界中3种基色光的混合原理,将红(Red)、绿(Green)和蓝(Blue)3中基色按照从0(黑)到255(白色)的亮度值在每个色阶中分配,从而指定其色彩。
3个字节 每个字节8位 表示0-255
黑色(0,0,0);白色(255,255,255);第一个字节B蓝色通道,蓝色为(255,0,0),第二个字节G绿色通道,绿色为(0,255,0);第三个字节R红色通道,红色为(0,0,255);
当3种基色的亮度值相等时,产生灰色 0:黑色 255:白色

2.HSV模式
H:色调,范围0~360,每隔60度表示一种基本颜色(其他度数在是相邻的基本度数之间的颜色):红(RGB(255,0,0))->黄(RGB(255,255,0))->绿(RGB(0,255,0))->青(RGB(0,255,255))->蓝(RGB(0,0,255))->紫(RGB(255,0,255))->红
S:饱和度,范围0~1,是白色(RGB(255,255,255))~根据H计算得到颜色 之间的比例
V:亮度,范围0~1,是黑色(RGB(0,0,0))~根据HS计算得到颜色 之间的比例

3.YUV模式 将亮度与色度分离
1)Y:亮度信息 即灰度值 是通过RGB输入信号来创建的,方法是将RGB信号的特定部分叠加到一起
2)UV:色彩信息 定义了颜色的两个方面-色调与饱和度,分别用Cr和CB来表示。其中,Cr反映了RGB输入信号红色部分与RGB信号亮度值之间的差异。而CB反映的是RGB输入信号蓝色部分与RGB信号亮度值之同的差异。。通过运算,YUV三分量可以还原出R(红),G(绿),B(蓝)。
3)YUV不像RGB那样要求三个独立的视频信号同时传输,所以YUV方式传送占用极少的频宽。
4)存储格式:YUV4:4:4,YUV4:2:2,YUV4:2:0
eg: (1) YUV 4:4:4采样,每一个Y对应一组UV分量。
(2) YUV 4:2:2采样,每两个Y共用一组UV分量。
(3) YUV 4:2:0采样,每四个Y共用一组UV分量。
二.代码
R G B H S V Y U V 九个通道分别显示代码

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


using namespace std;
using namespace cv;


int main()
{
    Mat img_h, img_s, img_v, imghsv;
    Mat Image;
    Image = imread("D://Libs//opencv310//opencv//sources//samples//data//aero1.jpg");      //原图
    vector<cv::Mat> hsv_vec;
    cvtColor(Image, imghsv, CV_BGR2HSV);

    // 分割hsv通道  
    split(imghsv, hsv_vec);
    img_h = hsv_vec[0];
    img_s = hsv_vec[1];
    img_v = hsv_vec[2];
    img_h.convertTo(img_h, CV_32F);
    img_s.convertTo(img_s, CV_32F);
    img_v.convertTo(img_v, CV_32F);
    double max_s, max_h, max_v;
    minMaxIdx(img_h, 0, &max_h);
    minMaxIdx(img_s, 0, &max_s);
    minMaxIdx(img_v, 0, &max_v);

    //输入RGB图像,转换成YUV并分离
    Mat imageY(Image.rows, Image.cols, 1);
    Mat imageU(Image.rows, Image.cols, 1);
    Mat imageV(Image.rows, Image.cols, 1);

    Mat imageYUV;
    cvtColor(Image, imageYUV, CV_BGR2YUV);
    vector<Mat> mv;
    split(Image, (vector<Mat>&)mv);

    imageY = mv[0].clone();
    imageU = mv[1].clone();
    imageV = mv[2].clone();

    //bgr
    for (int i = 0; i < 3; i++)
    {
        Mat bgr(Image.rows, Image.cols, CV_8UC3, Scalar(0, 0, 0));
        Mat temp(Image.rows, Image.cols, CV_8UC1);
        Mat out[] = { bgr };
        int from_to[] = { i, i };
        mixChannels(&Image, 1, out, 1, from_to, 1);
        //分别显示bgr
        imshow("bgr", bgr);
        waitKey();
    }

    //显示
    imshow("Y", imageY);
    waitKey();
    imshow("U", imageU);
    waitKey();
    imshow("Y_V", imageV);
    waitKey();

    imshow("h", img_h);
    waitKey();
    imshow("s", img_s);
    waitKey();
    imshow("h_v", img_v);
    waitKey();

    return 0;
}

三.函数分析
1**.split函数用法**
1)功能:通道分离,把一个彩色图像分割成3个通道
2)函数原型: void split(const Mat& src,Mat *mvBegin)
第一个参数为要进行分离的图像矩阵
第二个参数可以是Mat数组的首地址,或者一个vector对象
3)eg:

vector<Mat> Image;
Mat aImage[3];
split(src, aImage);              //利用数组分离
split(src, Image);               //利用vector对象分离

imshow("B",Image[0]);
imshow("G",Image[1]);
imshow("R",Image[2]);

注意: 不是所有格式的Mat型数据都能被使用保存为图片,目前OpenCV主要只支持单通道和3通道的图像,并且要求深度为8bit和16bit无符号(即CV_16U),所以其他一些数据类型是不支持的,比如说float型等。
如果Mat类型数据的深度和通道数不满足这些的要求,则需要使用convertTo()函数和cvtColor()函数来进行转换。
convertTo()函数负责转换数据类型不同的Mat,即可以将类似float型的Mat转换到imwrite()函数能够接受的类型。
而cvtColor()函数是负责转换不同通道的Mat,因为该函数的第4个参数就可以设置目的Mat数据的通道数(只是我们一般没有用到它,一般情况下这个函数是用来进行色彩空间转换的)。
另外也可以不用imwrite()函数来存图片数据,可以直接用通用的XML IO接口函数将数据存在XML或者YXML中

2.cvtColor()函数
1)功能:色彩图像转化为灰度图像,即转换不同通道的Mat。
2)原型

 void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 )

3)参数:
src:原图
dst:转化后的图像
code:是一个掩码,表示由src到dst之间是怎么转的,比如是彩色转为灰 度,还是彩色转为HSI模式
code的模式包括:
CV_RGB2GRAY:<彩色图像—>灰度图像>
CV_BGR2YCrCb, CV_RGB2YCrCb, CV_YCrCb2BGR, CV_YCrCb2RGB
BGR空间—>YChCb空间
CV_BGR2HSV, CV_RGB2HSV, CV_HSV2BGR, CV_HSV2RGB RGB空间—>HSV空间
dst:图像的波段数,这个值默认是0,它可以从参数code中推断

3.Mat.convertTo()的用法
1)原型:oclMat::convertTo(oclMat& m, int rtype, double alpha=1, double beta=0)
m:转为目标数据类型的矩阵
rtype: 指定目标数据类型,或者是depth(通道数),如果rtype:是负 值,那么目标矩阵的数据类型和源矩形的数据类型是一致的
alpha:基于尺度的变化值
beta:在尺度上的加和
转换数据类型不同的Mat,可以将类似float型的Mat转换到imwrite()可以读取的类型。

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值