修改视频每帧的每一列

时间:2013-06-15 04:01:55

标签: matlab video video-processing

我想编写一个程序,将视频作为输入,创建一个输出视频文件,并且(在一定数量的帧之后开始),开始逐帧地将修改后的帧写入输出文件。 修改将需要一次一个地处理单个像素列。

将此视为Matlab中要解决的问题,将每个帧作为矩阵......我想不出一种方法可以使这个计算易于处理。 我希望有人可以就如何开始解决这个问题提出建议。


以下是一些细节,如果它有帮助:

我对以下列方式转换视频感兴趣:

将视频视为一系列(MxN)矩阵,其中每个矩阵称为frame

  • 拍摄输入视频并为输出视频创建新文件
  • 对于输出视频的第(i)帧中的每列V,请将此列替换为 输入视频的frame(i + V - N)中的第V列。

例如:框架(i)的新的最右列(列N)将包含frame(i + N - N) = frame(i)...的列N,因此没有替换。框架(i)的新的第2列到最右列(第N-1列)将包含[frame(i+N-1-N) = frame(i-1)]的第N-1列。

为了使这项工作(即为了不用完前一帧),此列替换将从视频的第N帧开始。

1 个答案:

答案 0 :(得分:2)

那么......这基本上是一个从左到右运行的可变延迟?

正如你所说,你有两种解决方法:

a)使用大量内存 b)使用大量文件访问

您的内存需求随着视频大小的立方体功率而增加 - 每帧的大小增加,以及您需要打开或引用的前一帧数量增加。即加倍帧大小将需要每帧4x内存,并打开2x帧数。

我认为Matlab的内存管理可能会让人很难做到这一点。 1080p视频,除非你有一个漂亮的高端工作站。你呢?对720p视频的快速测试读取每帧1.2MB。那么1080p每帧约为5MB,你需要打开1920帧:需要大约10GB。

如果没有足够的内存,单独加载帧会更有效 - 否则你将使用页面文件,这比逐帧加载要慢。

您单独阅读每个框架的基本代码可能是这样的:

VR=VideoReader('My_Input_Video_Filename.avi');
VW=VideoWriter('My_Output_Video_Filename.avi','MPEG-4');

NumInFrames=get(VR,'NumberOfFrames');
InWidth=get(VR,'Width');
InHeight=get(VR,'Height');

OutFrame=zeros(InHeight,InWidth,3,'uint8');
for (frame=InWidth+1:NumInFrames)
    for (subindex=1:InWidth)
        CData=read(VR,frame-subindex);
        OutFrame(:,subindex,:)=CData(:,subindex,:);
    end
    writeVideo(VW,OutFrame);
end

这可能会很慢,我还没有完全检查它是否有效,但确实使用了最少的内存。

最小文件访问的最佳情况可能是使用环形缓冲区排列和最大内存量,如下所示:

VR=VideoReader('My_Input_Video_Filename.avi');
VW=VideoWriter('My_Output_Video_Filename.avi','MPEG-4');

NumInFrames=get(VR,'NumberOfFrames');
InWidth=get(VR,'Width');
InHeight=get(VR,'Height');

CDatas=read(VR,InWidth);
BufferIndex=1;
OutFrame=zeros(InHeight,InWidth,3,'uint8');
for (frame=InWidth+1:NumInFrames)
    CDatas(:,:,:,BufferIndex)=read(VR,frame);
    tempindices=circshift(1:InWidth,[1,-1*BufferIndex]);
    for (subindex=1:InWidth)
        OutFrame(:,subindex,:)=CDatas(:,subindex,:,tempindices(subindex));
    end
    writeVideo(VW,OutFrame);
    BufferIndex=mod(BufferIndex+1,InWidth);
end

缓冲区索引代码可能需要在那里进行一些调整,但沿着这些行的东西将是最小文件访问,最大内存使用解决方案。

对于具有更多或更少内存的给定PC,您可以在这两者之间实现某种解决方案(即在每次迭代中读取1到所有帧之间的某处)作为最佳情况。

对于这类任务来说,Matlab会很慢,但这将是一个很好的方法,可以让你的算法正确并找出索引错误和类似的东西。转换为编译语言可以大大提高速度 - 我在几个小时内将Matlab脚本转换为C#程序,并且比优化脚本的速度提高了10倍,其中所用的时间是文件读取次数

希望这有帮助,祝你好运!