我想计算一组图像或"视频"中每个像素的中位数。 但是,当 MATLAB 开始计算时,它需要很长时间,并且以索引错误随机完成。 为什么?
这是代码:
V = VideoReader('hall_monitor.avi');
info = get(V);
M = info.Width;
N = info.Height;
nb_frames_bk = 5;
v_pixel = zeros([nb_frames_bk 3]);
IB=zeros([M N 3],'double');
for i=1:M
for j=1:N
for k=1:nb_frames_bk
frm=read(V,k);
v_pixel(k,:)=frm(i,j,:);
end
IB(i,j,:)=median(v_pixel(:,:));
end
end
IB=uint8(IB);
imshow(IB);
这段代码可以从大量的重构中受益。 首先,当您可以读取一次帧,存储它们并在完成后使用它们时,您正在重新读取它们。
其次,遍历所有像素以计算中位数将非常慢。 根据代码中的外观,对于前nb_frames_bk
帧中的每个空间位置,收集这些帧中的所有 RGB 值并计算中值 RGB 值。
另外,作为次要说明,由于您错误地定义了输出矩阵,因此您得到了维度超过错误。 您将其定义为M x N
,M
是宽度,N
是高度。 这需要交换。 请记住,矩阵定义为高度第一,宽度第二。 但是,对于我将建议正确实现这一点的建议,这是不必要的。
指定帧范围,而不是一次读取一个帧。 这样,您将获得一个 4D 矩阵,其中前三个维度引用图像,第四维度表示帧号。 然后,您可以取第四维的中位数,以查找所有帧的 RGB 中值。
换句话说,只需这样做:
V = VideoReader('hall_monitor.avi');
nb_frames_bk = 5;
frms = read(V, [1 nb_frames_bk]);
IB = median(frms, 4);
imshow(IB);
这要好得多,切中要害,并保证更快。 您也不需要获取每个帧的宽度和高度,因为我们不再循环每个像素,因此不再需要它。