【问题标题】:How to split a binary file into different frames如何将二进制文件拆分为不同的帧
【发布时间】:2014-09-10 22:39:07
【问题描述】:

所以我有一个相当大的二进制文件,其中包含大约 70 个视频帧的信息。

我使用以下方法将二进制文件读入 MATLAB

fid = fopen('data.binary');
B = fread(fid,'int64');
fclose(fid);

但是变量B 仍然包含大量数据。所以我想知道我们如何拆分变量 B 以便我可以一帧一帧地获取数据。比如说 30 FPS。

这可能吗?

谢谢

PS:像素精度为 uint8,帧大小为 424X512。这是我正在使用的代码:

fid = fopen('C:\KinectData\Depth\Depth_Raw_0.binary');
B = fread(fid,'uint8');
fclose(fid);

B = uint8(B);

Z = B(1:217088)

n = 424; % No. of columns of T
BB = reshape(Z, n,[]);

BB = uint8(BB);

imshow(BB)

但图片还没有完全出现。

【问题讨论】:

  • 你知道每一帧的大小吗?除非您知道这是什么,否则不可能重建您的帧序列。另外,每个像素的精度是多少? uint8? uint16? int64 绝对不可能,因为据我所知,对于每像素 64 位的视频没有标准。这是彩色视频还是灰度视频?如果这是颜色,颜色像素是交错的,还是颜色通道被平面分开?在我们/我回答之前,您需要提供更多信息。
  • @rayreng 您好,感谢您的回复。框架的大小为 512x412。该视频是灰度视频。所以我只想把每一帧都当作一张图片,这样我就可以在 MATLAB 上单独处理它。我不太确定像素精度。我使用的代码来自这里:kinectstreamsaver.codeplex.com 页面底部,是的,深度视频来自 Kinect for XBOX 之一。
  • 好的,我看到了下面的代码。是的,一次可以读取 1 帧,但我不知道这些数据的结构。看起来您正在从单个帧中的多个流中读取。此外,您引用的代码看起来像是在尝试读取四元数数据,而不是深度数据。你能澄清一下吗?
  • 我引用的代码试图给出关节坐标的输出。但是,我对此并不真正感兴趣。我只想处理囚犯对象的深度图像。所以不是 fid = fopen('C:\KinectData\Skel\liTimeStamp.binary');我只是使用 fopen('C:\KinectData\Depth_data.binary') ,它只包含深度数据,没有其他内容。
  • @rayeng 再次嗨。我现在明白你在说数据类型。所以像素精度是 uint8 而不是 int64,每帧分辨率是 424X512。所以这是我使用的代码:查看编辑。再次感谢您的帮助!

标签: matlab image-processing computer-vision signal-processing kinect


【解决方案1】:

好的,鉴于您的 cmets,我们知道一些事情:

  1. 每帧为 424 x 512
  2. 视频中每个元素的精度为uint8
  3. 这是灰度视频,因此不考虑颜色
  4. 我假设您的数据是以行主要格式读取的。请记住,如果您想将数据作为矩阵读取,MATLAB 会以列主要格式读取数据,因此您必须进行转置操作,并确保首先将数据读入转置矩阵。

我要做的是将每一帧放入一个单元格数组中的cell 条目中。我这样做的原因是因为我们不知道你的序列中有多少帧。你说“70 左右”帧,因为我们不知道确切的数字,所以我们将动态填充元胞数组。

您编写的代码基本上是相同的,但我们将运行while 循环,直到我们从文件中读取的内容为空。在while 循环中,我们将一次读取一帧并将其存储到元胞数组中。我还将制作一个计数器来计算我们稍后必须计算的帧数,你会明白为什么。因此:

%// Open the file
fid = fopen('C:\KinectData\Depth\Depth_Raw_0.binary');
col = 424; %// Change if the dimensions are not proper
row = 512;

frames = {}; %// Empty cell array - Put frames in here
numFrames = 0; %// Let's record the number of frames too
while (true) %// Until we reach the end of the file:
    B = fread(fin, [col row],'uint8=>uint8'); %// Read in one frame at a time

    if (isempty(B)) %// If there are no more frames, get out
        break;
    end

    frames{end+1} = B.'; %// Transpose to make row major and place in cell array
    numFrames = numFrames + 1; %// Count frame
end

%// Close the file    
fclose(fid);

因此,如果您想访问第 ith 帧,您只需执行以下操作:

frm = frames{i};

作为额外奖励,您可以在 MATLAB 中将其作为movie 播放。我们可以做的是预先分配一个与播放电影兼容的电影结构,然后当您运行movie 命令时,它会为您播放帧。让我们指定 10 fps 的帧速率,以便它播放得足够慢以查看结果。因此,当您完成后,请执行以下操作:

%// Preallocate the movie structure array 
movieFrames(numFrames) = struct('cdata',[],'colormap',[]);

for idx = 1 : numFrames
    img = frames{idx};
    movieFrames(idx) = im2frame(cat(3, img, img, img));
end
figure;
imshow(movieFrames(1).cdata); %// Show first frame to establish figure size
movie(movieFrames, 1, 10); %// Play the movie once at 10 FPS

请注意,电影只能以彩色播放,因此您必须人为地将灰度图像变为彩色。彩色帧是一个 3D 矩阵,其中每个 2D 切片告诉您红色、绿色或蓝色的数量。对于灰度,这些切片中的每一个都是相同的,因此您只需为每个切片复制每个灰度帧。我使用cat 将灰度帧制作成3D 矩阵。我还使用im2frame将每个图像转换成与movie兼容的电影帧结构。

小警告

我无权访问您的二进制文件,因此此代码未经测试。使用风险自负!

【讨论】:

  • 这样的东西可以用于任何视频格式吗?
  • @Canadian_Republican 这仅适用于问题中提到的特定格式。例如,任何其他视频格式都必须使用 VideoReader 重新处理。加载视频并逐帧阅读的文档非常好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-30
  • 2018-02-20
  • 1970-01-01
  • 2021-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多