Linux43:cvtColor

1.cvtColor的用处和API讲解

1.cvtColor 的作用

cvtColor是OPENCV里面颜色转换的转换函数,它的功能非常强大。能够实现RGB图像转换成灰度图、灰度图转换成RGB图像、RGB转换成HSV等等。下面我们来看看

2.cvtColor API

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

第一个参数:输入的图像数据

第二个参数:输出的图像数据

第三个参数:颜色转换的标识符,下面是转换的图表。图像转化可以分为11个大类,分别是RGB->BGR RGB->5X5 RGB->GRAY RGB->CIEXYZ RGB->YyCrcb(YUV) RGB->HSV RGB->HLS RGB->CIELab RGB->CIELuv RGB->Bayer YUV420->RGB

第四个参数:目标图像通道数,默认为0

2.用代码实现cvtColor的颜色转换功能

这次代码主要是转换几个常见的格式,如RGB->YUV, YUV->RGB。具体的代码思路如下:

这个代码里面我们分别读取两种图片,一种是RGB图片、另外一种是YUV灰度图像、分别用cvtColor把RGB图像转换成YUV图像、把YUV灰度图像转换成RGB图像、最后用imwrite保存两种图片。下面是一些代码的实现截图:

1.调用 imread 读取 RGB 彩色图像

读取RGB彩色通道的图像,这张图片是一张车辆的图片

2. RGB 图像转换为 YUV 图像

调用cvtColor把三通道的RGB图像转换为YUV的灰度图像,这里使用的是COLOR_RGB2YUV。

3.调用 imread 读取 YUV 灰度图像

读取YUV的灰度图像,这张图片是一张灰度的汽车图像

4. YUV 图像转换为 RGB 图像

调用cvtColor把单通道的图像转换成RGB图像,调用的选项使用的是COLOR_YUV2RGB

5.把处理过后的两种图像保存

使用imwrite保存两种图像

最终的效果:

左边是处理后的YUV图像,右边是RGB图像

cs 复制代码
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>

using namespace cv; //Must Need Write cv
using namespace std;

int main()
{

    Mat src_bgr = imread("car.jpg");

    Mat img_yuv;
    cvtColor(src_bgr,img_yuv,COLOR_BGR2YUV);
    imwrite("car_yuv.jpg",img_yuv);

    Mat img_gray;
    cvtColor(src_bgr,img_gray,COLOR_BGR2GRAY);
    imwrite("car_gray.jpg",img_gray);

    Mat img_bgr;
    cvtColor(img_yuv,img_bgr,COLOR_YUV2BGR);
    imwrite("car_bgr.jpg",img_bgr);

    return 0;
}

car.jpg car.yuv

car.gray car.bgr

注:

1.灰度图

当你用灰度模式(例如 OpenCV 中的 cv2.IMREAD_GRAYSCALE 或相机 SDK 中的灰度采集)读取或采集图像时,图像数据变成了单通道

  • 彩色图 :每个像素由 3 个值组成(蓝、绿、红),是一个三维矩阵 (Height,Width,3)
  • 灰度图 :每个像素由 1 个值组成(亮度),是一个二维矩阵 (Height,Width)

在这个过程中,程序将彩色的信息通过加权平均算法(例如 Gray = 0.299R+0.587G+0.114BGray = 0.299R+0.587G+0.114B)合并成了一个亮度值。原本的 R、G、B 三个数值彻底丢失了,只剩下一个亮度值。

然后你对灰度图做了转BGR

gray 是单通道的图像

cvtColor(img_gray,img_bgr ,COLOR_GRAY2BGR)

这行代码做了以下事情:

  1. 输入:一个单通道的矩阵,数值是亮度 L。
  2. 输出:一个三通道的矩阵。
  3. 转换逻辑 :为了让单通道变成三通道,程序将唯一的亮度值 L 复制到了三个通道上。
  • 原来的像素值 L
  • 转换后的像素值 = (B = L, G = L, R = L)

当三个通道的值相等时,在屏幕上显示出来的就是灰度色(因为没有任何色彩倾向)。所以虽然图像格式变成了 BGR,但视觉上依然是灰色的。

2.YUV

yuv的图像用rgb读取,能转成彩色的。

YUV 和 RGB 一样,都完整保留了彩色信息,只是用不同的数学方式表达而已。

而之前你遇到的灰度转 BGR 之所以不行,是因为灰度图只保留了亮度,丢失了色彩信息。让我们深入看看区别:

YUV 格式本身就包含彩色信息

YUV(以及类似的 YCbCr)并不是黑白格式,而是一种彩色编码格式。它包含三个分量:

  • Y(亮度):描述图像的明暗程度(类似于黑白图)
  • U(Cb,蓝色色度):描述蓝色分量与亮度的差异
  • V(Cr,红色色度):描述红色分量与亮度的差异

关键点:虽然 Y 通道看起来像灰度图,但 UV 通道完整保留了颜色信息!这和灰度图(只有 Y,没有 UV)有本质区别。

CV_BGR2YUVCV_BGR2YUV_I420 的主要区别在于:前者生成的是"平面"但未压缩的格式,后者生成的是"平面且压缩"的格式

YUV420(家族名称)

├── I420(也叫 IYUV):YYYYYYYY UU VV (平面格式)

├── YV12:YYYYYYYY VV UU (平面格式,UV顺序交换)

├── NV12:YYYYYYYY UVUV (半平面格式)

└── NV21:YYYYYYYY VUVU (半平面格式)

  1. I420:Y平面 + U平面 + V平面
  2. NV12:Y平面 + UV交错平面(UV交替存储)
  3. YV12:Y平面 + V平面 + U平面(顺序不同)

3.cvtColor(img_yuv,img_to_bgr,CV_YUV2BGR);

COLOR_BGR2YUVI420 --> COLOR_YUV2BGR 有问题

当你将BGR转换为YUV_I420格式时,YUV图像的大小计算方式与BGR不同。I420格式要求图像的宽度和高度都是偶数,因为它的UV分量是下采样的(每2x2的Y块对应一组UV)。

COLOR_BGR2YUV --> COLOR_YUV2BGR 没有问题

相关推荐
前端摸鱼匠5 小时前
YOLOv11与OpenCV 联动实战:读取摄像头实时视频流并用 YOLOv11 进行检测(三)
人工智能·python·opencv·yolo·目标检测·计算机视觉·目标跟踪
大数据AI人工智能培训专家培训讲师叶梓6 小时前
Merlin:面向腹部 CT 的三维视觉语言基础模型
人工智能·计算机视觉·大模型·医疗·ct·视觉大模型·医疗人工智能
Fleshy数模11 小时前
解决OpenCV人脸检测报错:(-215:Assertion failed) !empty() 保姆级教程
人工智能·opencv·计算机视觉
H Journey15 小时前
openCV学习之-腐蚀
人工智能·opencv·学习
H Journey15 小时前
openCV图像学-二值化
人工智能·opencv·计算机视觉
大写-凌祁15 小时前
RescueADI:基于自主智能体的遥感图像自适应灾害解译
人工智能·计算机视觉·语言模型·自然语言处理·aigc
这张生成的图像能检测吗16 小时前
(论文速读)RUL- diff:基于生成扩散模型的剩余使用寿命预测深度学习框架
人工智能·计算机视觉·扩散模型·工业物联网·寿命预测
多年小白16 小时前
OpenAI 发布 DALL-E 4:4K分辨率+视频生成,AI图像创作进入新阶段
网络·人工智能·科技·深度学习·计算机视觉
格林威16 小时前
工业相机异常处理实战:断连重连、丢帧检测、超时恢复状态机
开发语言·人工智能·数码相机·计算机视觉·视觉检测·机器视觉·工业相机