首先声明一点,这里的YUV其实不是YUV,严格来说是YCbCr。这里就先这样称呼YUV吧。本文是关于YUV420格式的视频转成图片序列的。

关于YUV格式的图片,存储如下图所示:

举个例子,一个640*480的420的图片,读入matlab中的数据量为460800个数据。

460800/640*480=3/2。相当于每二个像素有3个数据。

如果想要把一个YUV文件转成RGB数据,那么必须要知道这个YUV文件是怎么以文件格式存储的。举个例子,假如一张4*4的大小的图片,它的YUV420格式的存储是这样的,如下图:

这只是一个示意图,假如一个图片是100*100像素的,那么它的存储文件中,前100*100=10000个字节是用来存储Y的。接下来2500个字节是用来存储U的,然后的2500个字节是用来存储V的。

当然这种格式也不是唯一的,我发现大多数的图片都是这种格式。当然还有其他的方式来验证一个图片是不是这样的格式。对于一个YUV420格式的图片来说,它一帧画面的数据量是它像素数的1.5倍,当然,我们肯定是知道一帧画面的分辨率的,然后可以读入YUV420视频文件中的1.5*X*Y个数据量,然后查看它对应有图片。如图所示:

红框中的是Y数据,蓝框中的是U数据,黄框中的是V数据。
现在应该可以得到一个YUV帧的YUV分量啦,接下来要做的就是把这三个分量加权求和,生成R,G,B分量啦。加权公式如下:
    R=1.164*(Y-16)+1.596*(VV-128);
    G=1.164*(Y-16)-0.813*(UU-128)-0.392*(VV-128);
    B=1.164*(Y-16)+2.017*(UU-128);

这里要注意一下,这里的YUV最好是double型的,我刚才始生成RGB的时候,YUV都是uint8型的,最后生成的图片颜色总是不对,换成double型的话,就没有问题啦,注意一下,double型的数据还要再归一化或者强制转换成uint8型的数据,才可以用imshow()显示出来。还有RGB三个分量矩阵中,大于255的量要设置成255,小于0的元素要设置为0。

本实验中用的图片恢复出来,如下图所示:

大功告成。

本程序实现代码如下图所示:

%函数功能:这个函数用于加载一个UYV序列文件
%入口参数:  path是包含要读写YUV序列的地址的字符串
%           x,y是这个图片的高与宽
%           start表示要从第几帧开始读取画面
%           count表示要读出的图片的张数
%出口参数:  picout(x,y,,3,count)表示出口参数
function [picout]=loadYUV(path,x,y,start,count);

% clear;
% clc

% x=288;
% y=352;
% count=10;
% path='e:\test-pic\flower.yuv';
fid=fopen(path,'r');

for ii=1:count
    fseek(fid,1.5*x*y*(ii-1+start-1),-1);
    pic=uint8(fread(fid,[y,1.5*x],'uint8'));
    pic=pic';
    Y=double(pic(1:x,:));
    u=double(pic(x+1:1.25*x,:));
    v=double(pic(1.25*x+1:1.5*x,:));
    for i=1:0.25*x
        U(2*i-1,1:y/2)=u(i,1:y/2);
        U(2*i,1:y/2)=u(i,y/2+1:y);
        V(2*i-1,1:y/2)=v(i,1:y/2);
        V(2*i,1:y/2)=v(i,y/2+1:y);
    end

UU=imresize(U,2);
    VV=imresize(V,2);

%     R=Y+1.140*(VV-128);
%     G=Y-0.395*(UU-128)-0.581*(VV-128);
%     B=Y+2.032*(UU-128);   
    R=1.164*(Y-16)+1.596*(VV-128);
    G=1.164*(Y-16)-0.813*(UU-128)-0.392*(VV-128);
    B=1.164*(Y-16)+2.017*(UU-128);

for i=1:x
    for j=1:y
    if R(i,j)<0
    R(i,j)=0;
    end
    if R(i,j)>255
    R(i,j)=255;
    end
    if G(i,j)<0
    G(i,j)=0;
    end
    if G(i,j)>255
    G(i,j)=255;
    end
    if B(i,j)<0
    B(i,j)=0;
    end
    if B(i,j)>255
    B(i,j)=255;
    end
    end
    end
    R=uint8(R);
    G=uint8(G);
    B=uint8(B);
    %R=R/255;G=G/255;B=B/255;
    picout(:,:,:,ii)=cat(3,R,G,B);
end
%imshow(picout(:,:,:,1));
上文只是一个子程序,但是绝对可用。

YUV420序列转成图片的更多相关文章

  1. 在linux下实现用ffmpeg把YUV420帧保存成图片

    在网上搜了很久相关的问题,但是好像没有一个在linux下跑得比较完整的例子,不过经过自己一番搜索和总结,终于做出来了,哈哈,看下面的代码吧. 这个例子可以保存成bmp或者jpeg格式的图片. 下面的结 ...

  2. 【小工具系列】Python + OpenCV 图片序列转换成视频

    图片序列转换成视频 最近一直在找一个工具,能够将一堆图片转化成视频.网上找了一些小软件,还有 win10 的照片自带的视频制作功能,都不是很满意. 又不想下载那些专业的视频剪辑软件大材小用. 然后找到 ...

  3. C# 将容器内容转成图片导出

    ///   将容器内容转成图片导出,这里的controller就是this         /// </summary>         private void OutTheContro ...

  4. 直接用<img> 的src属性显示base64转码后的字符串成图片

    直接用<img> 的src属性显示base64转码后的字符串成图片 <img src="base64转码后的字符串" ></img> 下面的图片 ...

  5. WPF 将PPT,Word转成图片

    在Office下,PowerPoint可以直接把每张幻灯片转成图片,而Word不能直接保存图片.所以只能通过先转换成xps文件,然后再转成图片. 一.PPT 保存为图片 /// <summary ...

  6. 把一个序列转换成严格递增序列的最小花费 CF E - Sonya and Problem Wihtout a Legend

    //把一个序列转换成严格递增序列的最小花费 CF E - Sonya and Problem Wihtout a Legend //dp[i][j]:把第i个数转成第j小的数,最小花费 //此题与po ...

  7. 把一个序列转换成非严格递增序列的最小花费 POJ 3666

    //把一个序列转换成非严格递增序列的最小花费 POJ 3666 //dp[i][j]:把第i个数转成第j小的数,最小花费 #include <iostream> #include < ...

  8. OpenGL中的深度、深度缓存、深度测试及保存成图片

    1.深度 所谓深度,就是在openGL坐标系中,像素点Z坐标距离摄像机的距离.摄像机可能放在坐标系的任何位置,那么,就不能简单的说Z数值越大或越小,就是越靠近摄像机. 2.深度缓冲区 深度缓冲区原理就 ...

  9. php 接收二进制流转换成图片

    php 接收二进制流转换成图片,图片类imageUpload.php如下: <?php /** * 图片类 * @author http://blog.csdn.net/haiqiao_2010 ...

随机推荐

  1. window.open实现模式窗口

    看了些文章,实现模式窗口有两种方式.window.showModalDialog以及window.open. 一.方式介绍 window.open()支持环境: JavaScript1.0+/JScr ...

  2. 【HDU】HDU5664 Lady CA and the graph

    原题链接 题解 距离省选只有一周了我居然才开始数据结构康复计划 这题很简单,就是点分树,然后二分一个值,我们计算有多少条路径大于这个值 对于一个点分树上的重心,我们可以通过双指针的方法求出它子树里的路 ...

  3. node.js版本管理

    Node安装 Node的安装需要依赖很多,如gcc等,首先我们需要将这些安装成功,用rpm命令查看下,果然我们并没有gcc等,所以要用yum进行安装(基于centos6.9版本): yum -y in ...

  4. LVM实现逻辑卷镜像

    本文系统 CentOS 6.5 x64 LVM的镜像功能,有点儿类似于Raid1,即多块儿磁盘互相同步,确保资料不会丢失. 1.在此添加4块物理硬盘,每块2G空间 2.将sdb.sdc.sdd.sde ...

  5. 大数据——hbase

    进入hbase hbase shell 部分命令清单 查询服务器状态   status 查询hbase版本   version 1. 创建一个表 create 'table1', 'tab1_id', ...

  6. 51Nod1553 周期串查询 字符串 哈希 线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1553.html 题目传送门 - 51Nod1553 题意 有一个串只包含数字字符.串的长度为n,下标 ...

  7. UOJ#310 【UNR #2】黎明前的巧克力 FWT 多项式

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ310.html 题目传送门 - UOJ#310 题意 给定 $n$ 个数 ,请你选出两个不相交的集合(两个 ...

  8. 046 Oracle执行慢的SQL

    -- 执行最慢的sql SELECT * FROM (SELECT sa.SQL_TEXT, sa.SQL_FULLTEXT, sa.EXECUTIONS as "exeCount" ...

  9. XX-Net的局域网共享代理方法

    局域网内有一台电脑安装了XX-net,将其共享给局域网内其他电脑,让其他电脑经这台电脑的XX-net配置访问网站. 一.电脑端操作1.在XXnet/data/gae_proxy目录下修改config. ...

  10. shell常用的系统变量

    $#:   命令行参数的个数 $n :   当前程序的第n个参数,n=1,2,-,9 $0:    当前程序的名称 $?:    执行上一个指令或函数的返回值 $*:    以"参数1,参数 ...