我想在MATLAB中实现一个非常简单的事情。我有一个4D数组的图像序列,格式如下:( framenumber,height,width,RGB)。
我的筹码很小,大小是:99 480 640 3
我想要达到的目的是检测n个连续图像(用固定相机拍摄的关于移动物体的图像)之间的运动是否发生变化。
为此,我最明显的想法是减去堆栈中的不同图像,并将它们保存在另一个堆栈中。
这是我试图运行的非常简单的代码:
vec = 1:size(stack,1)-5
dif = uint8(squeeze(abs(stack(vec,:,:,:) - stack(vec+5,:,:,:))));
然而它给了我内存不足的错误。
Error using -
Out of memory. Type HELP MEMORY for your options.
如果我不使用挤压(我需要在这里使用挤压吗?)我甚至得到关于内存不足的Windows系统错误。
作为一个后备,我写了一个for循环,这似乎有效,但只有当我使用uint8强制转换时。如果没有,它会耗尽内存并导致Windows系统错误。
for i = 1:size(stack,1)-5
dif(i,:,:,:) = uint8(abs(stack(i,:,:,:) - stack(i+5,:,:,:)));
end
此外,处理这个不太大的数据集(仅99帧)需要20秒。
你能告诉我如何编写一个不试图将所有内容保存在内存中的函数吗?这个命令应该只需要很少的内存来处理被比较的2个图像,但MATLAB会尝试出于某种原因在内存中执行所有操作。整个数据集的内存应该是91 MB,因此显然不应该是一个问题。
另外,你能解释我是否需要使用挤压吗?当我尝试获取单张图像时,
dif = stack(1,:,:,:) - stack(5,:,:,:);
生成4D数组,而
dif = squeeze(stack(1,:,:,:) - stack(5,:,:,:));
生成图像格式。但是在上面的for循环中,无论是否有挤压,它都会产生相同的结果。为什么会这样?
答案 0 :(得分:2)
关于SQUEEZE,stack
是4D矩阵,因此dif = stack(1,:,:,:) - stack(5,:,:,:);
也是4D矩阵,但第一维是单身。因此,当您将结果分配到现有矩阵(使用索引)时,元素将按顺序填充,并且任何单个维度都不起作用。但是,将结果放入一个新变量中,可以保持4D矩阵的形状......
如果所有值都是[0,255]范围内的整数,您应该知道您的数据类型,然后将整个图像堆栈转换为UINT8。正如我在评论中提到的,这种尺寸的4D双矩阵需要大约700MB的连续内存。
现在在for循环中,您应该预先分配dif
矩阵:
dif = zeros([99-5 480 640 3],'uint8');
for i = 1:size(stack,1)-5
dif(i,:,:,:) = abs( stack(i,:,:,:) - stack(i+5,:,:,:) );
end
最后尽管矢量化调用可能更快,但它们确实需要更多内存,因为它们尝试分配一个所需的整个空间(而不是使用仅需要空间来一次保存一个单个图像的循环)< / p>