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_BGR2YUV 和 CV_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 没有问题

相关推荐
AI的探索之旅4 天前
97 个 OpenCV 实例(三十):双目立体,从标定到点云
人工智能·opencv·计算机视觉
美狐美颜SDK开放平台4 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
词却4 天前
OpenCV学习:CNN 人脸检测
opencv
拉你进_教堂4 天前
小龙虾技能之【Parkinson‘s & Epileptic Behavior Recognition Skill | 帕金森癫痫行为识别技能】简介
人工智能·计算机视觉·多模态大模型·openclaw小龙虾技能
PascalXie4 天前
人形机器人的“眼睛“:多目视觉方案怎么选?
计算机视觉·机器人
普密斯科技4 天前
替代传统影像仪,摄像头磨切片测量新方案实测
计算机视觉·集成测试·测量
yyk333244 天前
OpenCV中的疲劳检测
opencv
宿州派大星4 天前
【Python实战】:基于 OpenCV + dlib 的传统换脸术原理与实战
opencv·python3.11·dlib
陈年老古董4 天前
MediaPipe 姿态检测与脸部关键点检测
笔记·python·opencv·学习·dlib
YOLO数据集集合4 天前
天空红外小目标检测数据集 | 红外小目标 天空目标检测 无人机检测 鸟类识别 低空安防9099期
人工智能·目标检测·计算机视觉·目标跟踪·无人机·无人机视角·直升机检测