如何使用Matlab从给定的yuv文件中提取Y、U和V分量?每个组件用于进一步的像素级操作
嘿,伙计们。我现在正在玩YUV文件。对于如何从yuv视频中提取y、u、v分量,您有什么建议吗?下面显示了一个示例。但我不知道哪一部分是我想要的有效组件。谢谢如何使用Matlab从给定的yuv文件中提取Y、U和V分量?每个组件用于进一步的像素级操作,matlab,video,buffer,rgb,yuv,Matlab,Video,Buffer,Rgb,Yuv,嘿,伙计们。我现在正在玩YUV文件。对于如何从yuv视频中提取y、u、v分量,您有什么建议吗?下面显示了一个示例。但我不知道哪一部分是我想要的有效组件。谢谢 % function mov = loadFileYuv(fileName, width, height, idxFrame) function [mov,imgRgb] = loadFileYuv(fileName, width, height, idxFrame) % load RGB movie [0, 255] from YUV
% function mov = loadFileYuv(fileName, width, height, idxFrame)
function [mov,imgRgb] = loadFileYuv(fileName, width, height, idxFrame)
% load RGB movie [0, 255] from YUV 4:2:0 file
fileId = fopen(fileName, 'r');
subSampleMat = [1, 1; 1, 1];
nrFrame = length(idxFrame);
for f = 1 : 1 : nrFrame
% search fileId position
sizeFrame = 1.5 * width * height;
fseek(fileId, (idxFrame(f) - 1) * sizeFrame, 'bof');
% read Y component
buf = fread(fileId, width * height, 'uchar');
imgYuv(:, :, 1) = reshape(buf, width, height).'; % reshape RESHAPE(X,M,N) returns the M-by-N matrix
%whose elements are taken columnwise from X.
%An error results if X does not have M*N elements
% read U component
buf = fread(fileId, width / 2 * height / 2, 'uchar');
imgYuv(:, :, 2) = kron(reshape(buf, width / 2, height / 2).', subSampleMat); % reshape and upsample
% read V component
buf = fread(fileId, width / 2 * height / 2, 'uchar');
imgYuv(:, :, 3) = kron(reshape(buf, width / 2, height / 2).', subSampleMat); % reshape and upsample
% normalize YUV values
% imgYuv = imgYuv / 255;
% convert YUV to RGB
imgRgb = reshape(convertYuvToRgb(reshape(imgYuv, height * width, 3)), height, width, 3);
% imgRgb = ycbcr2rgb(imgYuv);
%imwrite(imgRgb,'ActualBackground.bmp','bmp');
mov(f) = im2frame(imgRgb);
% mov(f).cdata = uint8(imgRgb);
% mov(f).colormap = [];
% imwrite(imgRgb,'ActualBackground.bmp','bmp');
%figure, imshow(imgRgb);
%name = 'ActualBackground.bmp';
%Image = imread(name, 'bmp');
%figure, imshow(Image);
end
fclose(fileId);
不确定我是否对YUV文件有一些基本的误解,但是如果你像我下面所做的那样编辑函数,你会在一个名为imgYUV的变量中为每一帧设置YUV组件。请注意,在此过程中可能会耗尽内存,您可能不希望一次性加载电影的所有帧
function imgYUV = loadFileYuv(fileName, width, height, idxFrame)
% load YUV data from YUV 4:2:0 file
fileId = fopen(fileName, 'r');
subSampleMat = [1, 1; 1, 1];
nrFrame = length(idxFrame);
%# preassign imgYUV. In case we can't keep everything in RAM,
%# it is better that the function crashes here, rather than after
%# having wasted time slowly filling up the memory.
%# Since the images are likely to be of class 'uint8',
%# you can save on a lot of memory by initializing
%# imgYUV as zeros(width/2,height/2,3,nrFrame,'uint8');
imgYUV = zeros(width/2 height/2, 3, nrFrame);
for f = 1 : 1 : nrFrame
%# search fileId position
sizeFrame = 1.5 * width * height;
fseek(fileId, (idxFrame(f) - 1) * sizeFrame, 'bof');
%# read Y component
buf = fread(fileId, width * height, 'uchar');
imgYuv(:, :, 1, f) = reshape(buf, width, height).';
%# read U component
buf = fread(fileId, width / 2 * height / 2, 'uchar');
imgYuv(:, :, 2, f) = kron(reshape(buf, width / 2, height / 2).', subSampleMat); % reshape and upsample
% read V component
buf = fread(fileId, width / 2 * height / 2, 'uchar');
imgYuv(:, :, 3, f) = kron(reshape(buf, width / 2, height / 2).', subSampleMat); % reshape and upsample
end
fclose(fileId);
我只想更改函数定义:
function [mov,imgYuv] = loadFileYuv(fileName, width, height, idxFrame)
不需要返回imgRgb,因为它与movnumelidxFrame.cdata相同
指定两个输出变量,您将在第二个变量中获得最后一帧的YUV组件
我会将函数更改为检查缓冲区是否为空,以避免在请求的帧数超过文件包含的帧数时出错
...
status = fseek(fileId, (idxFrame(f) - 1) * sizeFrame, 'bof');
if status == -1
error('Cannot read frame %d',idxFrame(f));
end
% read Y component
buf = fread(fileId, width * height, 'uchar');
if isempty(buf)
error('Cannot read frame %d',idxFrame(f));
end
imgYuv(:, :, 1) = reshape(buf, width, height).'; % reshape
% read U component
buf = fread(fileId, width / 2 * height / 2, 'uchar');
if isempty(buf)
error('Cannot read frame %d',idxFrame(f));
end
imgYuv(:, :, 2) = kron(reshape(buf, width / 2, height / 2).', subSampleMat); % reshape and upsample
% read V component
buf = fread(fileId, width / 2 * height / 2, 'uchar');
if isempty(buf)
error('Cannot read frame %d',idxFrame(f));
end
...
我使用以下代码来触发loadFileYuv函数。你认为这是正确的吗?nFrames=2000;mov1:nFrames=struct'cdata',zeros352288,3,'uint8','colormap',[];对于k=1:n帧movk.cdata=loadFileYuv。。。;end@yoursclark:只要将k作为第四个输入参数传递,看起来是正确的。行吗?嗨,乔纳斯。谢谢你的快速回复。我将k作为loadFileYuv函数的第四个输入参数。但是,当我试图通过键入“mov1.cdata”来显示cdata的内容时,像素结果都是零,这意味着帧数据没有存储在cdata字段中,不是吗?@yoursclark:看起来确实如此。我建议您在文件loadFileYuv中放置一个断点,单击编辑器中第一行数字旁边的破折号,应该会出现一个红点;当函数停止执行时,可以使用工具栏中的“步骤”按钮单步执行。这将让您了解loadFileYUV是否正常工作。将鼠标悬停在变量名上或在数组编辑器中查看它们是否都为零。谢谢Jonas。根据您的建议,我成功地获得了我想要的YUV组件。谢谢你的解释!谢谢你!你是对的。没有必要返回imgRgb,因为它不是我想要的。谢谢你指出这一点!