我为以下任务编写了代码:
从中心开始,增量为dr = 1pixel我想从我的图像中了解以下特征:
因此,我使用Matlab中的find函数搜索每个半径范围的矩阵索引。这是我的代码:
s = size(input image);
R = zeros(s(1),s(1)); %Initializing matrix R
x0 = ceil(s(1)/2); y0 = x0;
for i=1:s(1) %Calculation of matrix R
for j=1:s(2)
R(i,j) = sqrt((x0-j)^2 + (y0-i)^2);
end
end
r = 0; %Start of radius at 0
maxr = ceil(max(max(R))); %Maximum radius
R2 = gpuArray(R); %Move matrix R to GPU
while (r <= (maxr-dr))
N = 1*((R2>=r) & (R2<(r+dr))); %Logical matrix with 1 if r is in the radius range
indnew = find(N); %Find the indices of non-zero elements
indices = vertcat(indices,indnew); %Create large vector with the founded indices
indices = vertcat(indices,(-1)); %Append stop-sign -1
r = r + dr;
end
ind2 = int32(gather(indices)); %Get indices from GPU to CPU
此代码的作用如下: 在这一行
N = 1 *((R2> = r)&amp;(R2&lt;(r + dr)));
我得到一个逻辑矩阵作为答案,将其乘以1.如果r在半径范围内,矩阵的值为1。然后我使用find函数搜索矩阵的索引。但是对于2000x2000像素的图像尺寸,我需要30秒(使用gpuArray(R))并且像一分钟没有将R移动到GPU。
所以似乎find函数非常慢,但我不知道一个和我编写的代码一样稳定的解决方案。
有没有人知道如何以更优雅和更快的方式找到所需的矩阵索引???
请记住,我现在在while循环中有1400次循环运行。甚至可以像使用find函数一样更快地获得索引吗?
提前谢谢!!
答案 0 :(得分:0)
也许使用类似直方图的方法会有所帮助。 (histcounts) 将R2的元素从[0:dr:maxr]
中分成二进制位答案 1 :(得分:0)
我最近完成了这个计算。关键是要避免发现。你不需要它,使用逻辑寻址......
my &double = * * 2; # WhateverCode
my &double = * × 2; # ditto
my &double = { $_ * 2 }; # bare block
my &double = { $^n * 2 }; # block with positional placeholder
my &double = -> $n { $n * 2 }; # pointy block
my &double = sub ( $n ) { $n * 2 } # anon sub
my &double = anon sub double ( $n ) { $n * 2 } # anon sub with name
my &double = &infix:<*>.assuming(*,2); # curried
my &double = &infix:<*>.assuming(2);
sub double ( $n ) { $n * 2 } # same as :( Any $n )
您还没有告诉我们您希望索引的内容,但可能您希望以某种方式累积它们。在这种情况下,accumarray的速度提高了几个数量级:
valsForRanger = inputImage((R>=r) & (R<(r+dr));
numValsForRanger = numel(valsForRanger);
PS。注意,GPU在这里是一个红鲱鱼。我不会用它。