对于 YUV 所表示的图像,Y 和 UV 分量是分离的。如果只有 Y 分量而没有 UV 分离,那么图像表示的就是黑白图像。彩色电视机采用的就是 YUV 图像,解决与和黑白电视机的兼容问题,使黑白电视机也能接受彩色电视信号。

人眼对色度的敏感程度低于对亮度的敏感程度。主要原因是视网膜杆细胞多于视网膜锥细胞,其中视网膜杆细胞的作用就是识别亮度,视网膜锥细胞的作用就是识别色度。所以,眼睛对于亮度的分辨要比对颜色的分辨精细一些。

利用这个原理,可以把色度信息减少一点,人眼也无法查觉这一点。

所以,并不是每个像素点都需要包含了 Y、U、V 三个分量,根据不同的采样格式,可以每个 Y 分量都对应自己的 UV 分量,也可以几个 Y 分量共用 UV 分量。相比 RGB,能够节约不少存储空间。

YUV 4:4:4采样方式与 RGB 图像大小是一样的。
YUV 4:2:2相比 RGB, 节省了三分之一的存储空间。
YUV 4:2:0相比 RGB, 节省了一半的存储空间。

设实际宽高为 w*h 的图像,如果是 RGB 格式,那么他的数据量为 w*h*3
如果是 yuv420 格式,那么他的数据量为 w*h*1.5
因为 yuv4:4:4 的数据量等于RGB数据量,而 yuv4:4:4 yuv4:2:0 数据量的2倍,所以 yuv4:2:0 的数据量为 w*h*3/2

yuv420sp 转化得到 RGB 的步骤:
  • 1.当我们拿到一帧图像的yuv原始数据后,首先需要明确拿到的是以下哪种yuv数据: yuv4:4:4 yuv4:2:2 yuv4:2:0 。并且,我们都会知道给对应图像的宽和高,因为这都是驱动配置给出的。如果你是从yuv元素数据中截取出来的某roi区域的yuv数据,那么你也应该知道该roi的宽和高。注意,此时的宽和高是指图像的宽和高,不是指代图像数据码流排列的行数和列数。
  • 2.把原始yuv数据通过构造 cv::Mat 格式封装起来,此时的 cv::Mat 的宽( .cols )和高( .rows )就需要变化了,因为yuv格式和RGB格式的数据量是不一样的,yuv格式如果不是 yuv4:4:4 (yuv数据量为 w*(h*3) )的话,那么yuv格式的数据量是一定比RGB少的。所以,此时如果是 yuv420 格式,就根据 yuv420 格式的特点,把 cv::Mat 的宽高设置为 w*(h*1.5) ,且必须为单通道,注意这里宽度不变,是在高度上延伸。yuyv原始数据变成 cv::Mat 格式后,你如果直接 imshow 显示的话,图像会变高。转化成RGB格式后才会恢复为正常宽和高。
  • 3.然后再通过 cv::cvtColor(yuyv_img, rgb_img, cv::COLOR_YUV420sp2RGB); 转化得到RGB图像。

注意构造yuyv的 cv::Mat 时通道类型是 CV_8UC1 ,而构造RGB的 cv::Mat 时通道类型是 CV_8UC3 .

cv::Mat yuyv_img =
    cv::Mat(box.height * 3 / 2, box.width, CV_8UC1,
            const_cast<unsigned char *>(yuv_raw.data()));
if (!yuyv_img.data) {
  std::cout << "empty yuyv_img"<< std::endl;
cv::Mat rgb_img = cv::Mat(box.height, box.width, CV_8UC3);
cv::cvtColor(yuyv_img, rgb_img, cv::COLOR_YUV420sp2RGB);

可参考下面两篇文章来理解YUV:
一文理解 YUV
YUV色彩格式总结

设实际宽高为w*h的图像,如果是RGB格式,那么他的数据量为w*h*3;如果是yuv420格式,那么他的数据量为w*h*1.5因为yuv4:4:4的数据量等于RGB数据量,而yuv4:4:4是yuv4:2:0数据量的2倍,所以yuv4:2:0的数据量为w*h*3/2。从yuv420sp转化得到rgb的步骤:1.当我们拿到一帧图像的yuv原始数据后,首先需要明确拿到的是以下哪种yuv数据:yuv4:4:4、yuv4:2:2、yuv4:2:0。并且,我们都会知道给对应图像的宽和高,因为这都是驱动配置给 0.1 灰度模式 也就是灰度图(黑白照片),每个像素只有明暗变化,用0~255共256个亮度级来表示,用8个bit来表示,所以每个像素信息用8bit储存. 0.2 位图模式(二值图像) 即只有纯黑和纯白两种亮度,没有渐变的亮度级,通常用0表示纯黑,1表示纯白,所以每个像素信息用1bit表示即可 0.3 RGB模式:基于发光体(电子产品)的色彩模式 static long int cgu_tab[256]; static long int cgv_tab[256]; static long int tab_76309[256]; static unsigned char clp[1024]; //for clip in CCIR601 void init_yuv420p_table()
通过FFMPEG 得到mov视频解码后的一个Frame,它是YUV420P的图像,我要把它换成方便显示的JPEG图像。 代码片断如下所示 av_image_copy(_data, _linesize, (const uint8_t **)avframe->data, avframe->linesize, _pix_fmt, _width, _height); cv::...
  YUV格式哟很多种,本篇记录的格式为YUV420。 有关YUV420的详细介绍,可以参考资料:1、图文详解YUV420数据格式 http://blog.csdn.net/jefry_xdz/article/details/7931018   首先yuv420的存储大小为:width * he