减去子数组会给出MATLAB中的内存不足错误

时间:2011-10-29 12:05:21

标签: arrays image matlab image-processing

我想在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循环中,无论是否有挤压,它都会产生相同的结果。为什么会这样?

1 个答案:

答案 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>