如何把未压缩的.avi文件批量地转为.yuv文件(yuv420)?

clear
clc
cd('F:\qcifAvi');

myFile = dir('*.avi');  % 无损压缩的.avi文件集合
for i = 1 : length(myFile)  % qcifAvi目录下.avi文件的个数为: length(myFile)
    name{i} = myFile(i).name(1:length(myFile(i).name));  % .avi文件全名
    videoName = name{i};
    
    obj = mmreader(videoName); % multimedia reader
    vidFrames = read(obj);    % 所有帧
    numFrames = obj.numberOfFrames; % 帧数

    for k = 1 : min(numFrames, 300)
         mov(k).cdata = vidFrames(:,:,:,k);
         mov(k).colormap = []; % 不可少
    end

    fileName{i} = myFile(i).name(1:length(myFile(i).name) - length('-qcif_original.avi'));  % .avi文件的部分名
    fileName{i} = [fileName{i}, '_qcif.yuv'];
    saveFileYuv(mov, fileName{i});
end

 

% 把mov结构体存成YUV420
function saveFileYuv(mov, fileName)

fid = fopen(fileName, 'w');

dim = size(mov(1).cdata); % dim是一个向量,比如[144 176 3]
height = dim(1);
width = dim(2);
numFrames = length(mov);    % numFrames是帧的数量

for f = 1 : numFrames
    imgRgb = frame2im(mov(f)); % matlab内部函数

    % rgb2yuv (matlab中转换函数常用的命名格式,还比如num2str)
    imgYuv = reshape(rgb2yuv(reshape(imgRgb, height * width, 3)), height, width, 3);

    % Y分量
    buf = reshape(imgYuv(:, :, 1).', [], 1);
    fwrite(fid, buf, 'uchar');

    % U分量
    buf = reshape(imgYuv(1 : 2 : end, 1 : 2 : end, 2).', [], 1); % 下采样
    fwrite(fid, buf, 'uchar');

    % V分量
    buf = reshape(imgYuv(1 : 2 : end, 1 : 2 : end, 3).', [], 1); % 下采样
    fwrite(fid, buf, 'uchar');
end

fclose(fid);
function yuv = rgb2yuv(rgbUint8)  % rgbUint8是一个矩阵,比如大小为25344*3

[m, n] = size(rgbUint8);

% 下面这个转换非常重要,以前错过,如果是uint8, 那么负数将被转换成0,所以要转成double型
rgb = double(rgbUint8);

% 构造一个零矩阵,便于统一操作,免得用循环. 好方法.
yuv = uint8(zeros(m, 3));

yuv(:, 1) = min( 255, max(0, 0.299 * rgb(:, 1) + 0.587 * rgb(:, 2) + 0.114 * rgb(:, 3)) );
yuv(:, 2) = min( 255, max(0, -0.1687 * rgb(:, 1) - 0.3313 * rgb(:, 2) + 0.5 * rgb(:, 3) + 128) );
yuv(:, 3) = min( 255, max(0, 0.5 * rgb(:, 1) - 0.4187 * rgb(:, 2) - 0.0813 * rgb(:, 3) + 128) );

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值