matlab:优化用于计算多尺度圆形邻域中的统计的代码 [英] matlab: optimizing code for computing statistics in multi-scale circular neighborhoods
问题描述
我有一堆图像( 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
withdouble(n)/ sum(n(:))
as filtermean: use
imfilter
withdouble(n)/sum(n(:))
as filterimgstack_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屋!