我正在尝试学习MATLAB,我遇到的第一个问题是用静态相机和移动物体来猜测图像序列的背景.首先,我只是想在一段时间内对像素进行均值或中值,所以它只是我想要应用于4维数组的一行的单个函数.
我已将RGB图像加载到具有以下尺寸的4维阵列中:
uint8 [ num_images, width, height, RGB ]
这是我写的函数,包括4个嵌套循环.我使用预分配,但仍然非常慢.在C中我相信这个函数可以运行至少快10倍-20倍,我认为在CUDA上它实际上可以实时运行.在MATLAB中,4个嵌套循环大约需要20秒.我的堆栈是100个图像,尺寸为640x480x3.
function background = calc_background(stack)
tic;
si = size(stack,1);
sy = size(stack,2);
sx = size(stack,3);
sc = size(stack,4);
background = zeros(sy,sx,sc);
A = zeros(si,1);
for x = 1:sx
for y = 1:sy
for c = 1:sc
for i = 1:si
A(i) = stack(i,y,x,c);
end
background(y,x,c) = median(A);
end
end
end
background = uint8(background);
disp(toc);
end
你能告诉我如何更快地制作这段代码吗?我尝试过以某种方式直接从数组中仅使用索引获取数据,并且它似乎更快.它在3秒内与20秒完成,因此只需编写一个较小的函数就可以达到7倍的性能差异.
function background = calc_background2(stack)
tic;
% bad code, confusing
% background = uint8(squeeze(median(stack(:, 1:size(stack,2), 1:size(stack,3), 1:3 ))));
% good code (credits: Laurent)
background=uint8((squeeze(median(stack,1)));
disp(toc);
end
所以现在我不明白MATLAB是否可以这么快,那么为什么嵌套循环版本如此之慢?我没有进行任何动态调整大小,MATLAB必须在内部运行相同的4个嵌套循环.
为什么会这样?
有没有办法让嵌套循环快速运行,就像在C中自然发生一样?
或者我是否应该习惯于用这种疯狂的单行语句编程MATLAB来获得最佳性能?
更新
谢谢你所有的好答案,现在我了解了很多.我的原始代码堆栈(:,1:大小(堆栈,2),1:大小(堆栈,3),1:3))没有任何意义,它与堆栈完全相同,我只是幸运使用中位数的默认选项,将第一维用于其工作范围.
我想最好问一下如何在另一个问题上写一个有效的问题,所以我在这里问: