【问题标题】:Matlab: Remove loop from codeMatlab:从代码中删除循环
【发布时间】:2014-06-10 11:41:44
【问题描述】:

flow 是一个 4D 双矩阵,其第四维总是2。我想在不使用循环的情况下实现这个循环。

本质上,对于第三维中的每个索引,我想将flow1 划分为大小为block-size 的正方形块,然后计算每个块的第四维值的平均值,然后将这些值分配回该块中所有元素的相应第四维。

典型值为 [height width N block_size] = [ 480 640 100 8] 。保证block_sizeheightwidth 的一个因子

[height,width,N,~]  = size(flow1);
reduced_flow = zeros(size(flow1));
for ii = 1:block_size:height
    for jj = 1:block_size:width
        for k = 1:N
            reduced_flow(ii:ii+block_size-1,jj:jj+block_size-1,k,1) = mean(mean(flow1(ii:ii+block_size-1,jj:jj+block_size-1,k,1),1),2);
            reduced_flow(ii:ii+block_size-1,jj:jj+block_size-1,k,2) = mean(mean(flow1(ii:ii+block_size-1,jj:jj+block_size-1,k,2),1),2);
        end
    end
end

示例

 flow1 = round(10*rand(4,4,2,2));
 block_size = 2;
 [flow1 reduced_flow]

 ans(:,:,1,1) =

     6.0000    4.0000    1.0000         0    4.0000    4.0000    2.2500    2.2500
     6.0000         0    2.0000    6.0000    4.0000    4.0000    2.2500    2.2500
          0    5.0000    1.0000    3.0000    3.2500    3.2500    2.7500    2.7500
     6.0000    2.0000    2.0000    5.0000    3.2500    3.2500    2.7500    2.7500


 ans(:,:,2,1) =

     7.0000    1.0000    3.0000    4.0000    4.5000    4.5000    2.7500    2.7500
     5.0000    5.0000    2.0000    2.0000    4.5000    4.5000    2.7500    2.7500
     5.0000    9.0000    6.0000    9.0000    6.7500    6.7500    5.5000    5.5000
     4.0000    9.0000    6.0000    1.0000    6.7500    6.7500    5.5000    5.5000


 ans(:,:,1,2) =

     1.0000    9.0000    7.0000    5.0000    3.2500    3.2500    7.5000    7.5000
     2.0000    1.0000   10.0000    8.0000    3.2500    3.2500    7.5000    7.5000
     7.0000   10.0000    3.0000    8.0000    6.2500    6.2500    4.0000    4.0000
     3.0000    5.0000    4.0000    1.0000    6.2500    6.2500    4.0000    4.0000


 ans(:,:,2,2) =

     2.0000    3.0000    7.0000    7.0000    2.7500    2.7500    6.5000    6.5000
     4.0000    2.0000    5.0000    7.0000    2.7500    2.7500    6.5000    6.5000
     1.0000    2.0000    9.0000    6.0000    4.2500    4.2500    4.5000    4.5000
     5.0000    9.0000    1.0000    2.0000    4.2500    4.2500    4.5000    4.5000

【问题讨论】:

  • 如果你解释一下代码的作用会更好
  • @LuisMendo 对不起,我会知道的,有事我不得不走了
  • 所以按照你上面的想法,你想在第一个二维[480, 640] 中取一个子矩阵,然后在第四维[8] 中计算平均值,而忽略第三维[100]?您要分配给第 4 维中所有这些值的平均值。 3维应该怎么办?忽略它,删除它?我理解你的问题吗?
  • @TheMinion 你的问题我很清楚,我已经编辑了解释。
  • 我猜你现在正在处理它,但在那个例子中,你会期望什么样的block-size得到什么样的答案?

标签: arrays matlab multidimensional-array vectorization


【解决方案1】:

方法 1

flow11 = reshape(flow1,size(flow1,1),[]);
fun = @(block_struct) mean2(block_struct.data);
mat1 = blockproc(flow11,[block_size block_size],fun);
mat2 = imresize(mat1,block_size ,'nearest');
reduced_flow = reshape(mat2,size(flow1));

方法二

t1 = sum(reshape(sum(reshape(flow1,block_size,[])),height/block_size,block_size,[]),2)./block_size^2;
t2 = reshape(t1,1,1,[]);
t3 = t2(ones(1,block_size),ones(1,block_size),:,:);
t4 = reshape(permute(t3,[1 3 2]),size(t3,1)*size(t3,3),[]);
out = permute(reshape(t4,height,size(t4,1)/height,[]),[1 3 2]);
reduced_flow = reshape(out,size(flow1));

【讨论】:

  • 对于size(flow) = [480 640 51 2],执行时间从 105 秒(循环)增加到 216 秒(你的代码)。另外,b = reduced_flow_loop ~= reduced_flow_divakar ;error = sum(b(:)) 给了error as 3788608
  • @Nishant 查看刚刚添加的方法 2。
  • @Nishant 如果您对 rand 值进行错误检查,我建议使用最大差异来避免浮点计算问题,例如 - err1 = reduced_flow(:) - reduced_flow2(:);max_error = max(err1(:))
  • 如果flow1的大小是[480 640 100 1]我可以这样做吗
  • 这没有花费时间,我的意思是几乎在我按下 enter 时输出就出现了,所以我没有分析代码。我尝试过的那个大小,在循环生成的值和你的代码之间出现了相当大的错误,我没有正确知道错误的实际值
猜你喜欢
  • 2014-07-25
  • 1970-01-01
  • 2011-11-03
  • 1970-01-01
  • 2014-08-13
  • 2016-05-05
  • 2013-12-03
  • 1970-01-01
  • 2021-05-10
相关资源
最近更新 更多