matlab:优化用于计算多尺度圆形邻域中的统计的代码 [英] matlab: optimizing code for computing statistics in multi-scale circular neighborhoods

查看:173
本文介绍了matlab:优化用于计算多尺度圆形邻域中的统计的代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一堆图像( imgstack ),我想用它来计算一些统计数据(例如mean,std,median )在多尺度的圆形社区。对于堆栈中的每个图像( currscale ),要应用的圆形邻域的大小预先存储在向量 imgstack_radii(ss)。圆形neighboorhoods的大小在堆栈上的图像上变化。圆形滤波器半径的一些示例值为 1.4142,1.6818,2.0000,2.3784

I've a stack of images (imgstack) over which I would like to compute some statistics (e.g. mean, std, median) in multi-scale circular neighborhoods. For each image on the stack (currscale), the size of the circular neighborhood to be applied is pre-stored in a vector imgstack_radii(ss). The size of the circular neighboorhoods change across the images on the stack. Some example values for the radius of the circular filters are 1.4142,1.6818,2.0000,2.3784.

下面的代码然而,由于我的堆栈大小相当大( 1200x1200x25 ),计算时间非常昂贵。我想知道是否有一种优化/矢量化代码的方法?任何建议都表示赞赏!

The code below does the work, however, since the size of my stack is pretty big (1200x1200x25) the computational time is very expensive. I was wondering if there's a way to optimize/vectorize the code? Any suggestions are appreciated!

[rows, cols, scls] = size(imgstack);
imgstack_feats = cell(scls,1);
[XX, YY] = meshgrid(1:cols, 1:rows);
for rr=1:rows
    for cc=1:cols
        distance = sqrt( (YY-rr).^2 + (XX-cc).^2  );

        for ss=1:scls
            % imgstack_radii contains the radius associated to a given scale, i.e.: radii = scale * sqrt(2)
            mask_feat_radii = (distance <= imgstack_radii(ss));
            currscale       = imgstack(:,:,ss);
            responses       = currscale(mask_feat_radii);

            imgstack_feats{ss}(rr,cc,:) = [mean(responses), std(responses), median(responses)];
        end
    end
end

@Shai的反馈后和@Jonas,最终的代码如下所示。谢谢你们!

After the feedback of @Shai and @Jonas, the final code looks like below. Thanks guys!

function disk = diskfilter(radius)
    height  = 2*ceil(radius)+1;
    width   = 2*ceil(radius)+1;
    [XX,YY] = meshgrid(1:width,1:height);
    dist    = sqrt((XX-ceil(width/2)).^2+(YY-ceil(height/2)).^2);
    circfilter = strel(dist <= radius);
end

for ss=1:scls
    fprintf('\tProcessing scale: %d radii: %1.4f\n', ss, imgstack_radii(ss));
    disk      = diskfilter(imgstack_radii(ss));
    neigh     = getnhood( disk );

    imgstack_feats{ss}(:,:,1) = imfilter( imgstack(:,:,ss), double(neigh)/sum(neigh(:)), 'symmetric' );

    tmp = imfilter( imgstack(:,:,ss).^2, double(neigh)/sum(neigh(:)), 'symmetric' );
    imgstack_feats{ss}(:,:,2) = sqrt( tmp - imgstack_feats{ss}(:,:,1) );

    imgstack_feats{ss}(:,:,3) = ordfilt2( imgstack(:,:,ss), ceil( sum(neigh(:))/2 ), neigh );
end


推荐答案

您可以使用替换所有操作过滤器,应该明显更快。

对于每个 imagestack_radii ,首先创建一个圆形掩码:

You can replace all operations using filters, which should be significantly faster.
For each imagestack_radii, first create a circular mask:

n = getnhood( strel('disk', imagestack_radii(s), 0 ) );




  • 意思是:使用 imfilter with double(n)/ sum(n(:)) as filter

    • mean: use imfilter with double(n)/sum(n(:)) as filter

      imgstack_feats{ss}(:,:,1) = imfilter( imgstack(:,:,ss), double(n)/sum(n(:)), 'symmetric' );
      


    • 标准:一旦你有了平均值,就可以用

    • std: once you have the mean, you can compute the second moment using

      tmp = imfilter( imgstack(:,:,ss).^2, double(n)/sum(n(:)), 'symmetric' );
      imgstack_feats{ss}(:,:,2) = sqrt( tmp - imgstack_feats{ss}(:,:,1) );
      


    • 中位数:使用 ordfilt2

      imgstack_feats{ss}(:,:,3) = ordfilt2( imgstack(:,:,ss), ceil( sum(n(:))/2 ), n );
      


    • 这篇关于matlab:优化用于计算多尺度圆形邻域中的统计的代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆