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

相关推荐
明月醉窗台2 小时前
Torch-TensorRT 相关
人工智能·目标检测·计算机视觉·目标跟踪
沃达德软件2 小时前
视频监控烟火识别技术
图像处理·人工智能·目标检测·计算机视觉·目标跟踪·视觉检测·超分辨率重建
不懒不懒2 小时前
【Opencv计算机视觉-模版匹配】
人工智能·opencv·计算机视觉
Daydream.V2 小时前
Opencv——模板匹配附项目实战(一)
人工智能·opencv·计算机视觉
sali-tec11 小时前
C# 基于OpenCv的视觉工作流-章33-Blod分析
图像处理·人工智能·opencv·算法·计算机视觉
Qt学视觉12 小时前
AI2-Paddle环境搭建
c++·人工智能·python·opencv·paddle
bst@微胖子16 小时前
OpenCV 案例四【人脸识别】
人工智能·opencv·计算机视觉
bryant_meng18 小时前
【Reading Notes】(7.11)Favorite Articles from 2024 November
人工智能·深度学习·计算机视觉·aigc·资讯
Sagittarius_A*19 小时前
傅里叶变换:从空域到频域的图像分析【计算机视觉】
图像处理·人工智能·python·opencv·计算机视觉·傅里叶变换·频域滤波