我有一张要在圆形邻域内计算局部直方图的图像。邻域的大小由radius给出。尽管下面的代码可以完成工作,但是在计算上却很昂贵。我运行了探查器,访问圆形邻域内像素的方式已经很昂贵了。

是否有可能基于矢量化进行任何类型的改进/优化?还是例如将邻域存储为列?
我在post中发现了一个类似的问题,所提出的解决方案完全符合以下代码的精神,但是该解决方案仍然不适合我的情况。任何想法都非常受欢迎:-)暂时想象一下,该图像是二进制的,但该方法也应该理想地适用于灰度图像:-)

[rows,cols] = size(img);
hist_img      = zeros(rows, cols, 2);
[XX, YY]      = meshgrid(1:cols, 1:rows);
for rr=1:rows
        for cc=1:cols
            distance      = sqrt( (YY-rr).^2 + (XX-cc).^2  );
            mask_radii = (distance <= radius);
            bwresponses   = img(mask_radii);
            [nelems, ~]   = histc(double(bwresponses),0:255);
            % do some processing over the histogram
            ...
        end
end

编辑1 根据收到的反馈,我尝试更新解决方案。但是,这还不正确
radius = sqrt(2.0);
disk   = diskfilter(radius);
fun    = @(x) histc( x(disk>0), min(x(:)):max(x(:)) );
output = im2col(im, size(disk), fun);

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 = (dist <= radius);
end

最佳答案

按照我在answer to a similar question中描述的技术,您可以尝试执行以下操作:

  • 计算来自特定体素的索引偏移,该偏移使您到达半径
  • 内的所有邻居
  • 确定哪些体素具有距离边缘
  • 至少半径的所有邻居
  • 为所有这些体素计算邻居
  • 为每个邻域生成您的直方图

  • 将其向量化并不难,但请注意
  • 邻居大时会很慢
  • 它涉及生成一个中间矩阵NxM(N =图像中的体素,M =邻域中的体素),该矩阵可以得到非常大的

  • 这是代码:
    % generate histograms for neighborhood within radius r
    A = rand(200,200,200);
    radius = 2.5;
    tic
    sz=size(A);
    [xx yy zz] = meshgrid(1:sz(2), 1:sz(1), 1:sz(3));
    center = round(sz/2);
    centerPoints = find((xx - center(1)).^2 + (yy - center(2)).^2 + (zz - center(3)).^2 < radius.^2);
    centerIndex = sub2ind(sz, center(1), center(2), center(3));
    
    % limit to just the points that are "far enough on the inside":
    inside = find(xx > radius+1 & xx < sz(2) - radius & ...
        yy > radius + 1 & yy < sz(1) - radius & ...
        zz > radius + 1 & zz < sz(3) - radius);
    
    offsets = centerPoints - centerIndex;
    allPoints = 1:prod(sz);
    insidePoints = allPoints(inside);
    indices = bsxfun(@plus, offsets, insidePoints);
    
    hh = histc(A(indices), 0:0.1:1);  % <<<< modify to give you the histogram you want
    toc
    

    相同代码的2D版本(可能是您所需要的,并且速度要快得多):
    % generate histograms for neighborhood within radius r
    A = rand(200,200);
    radius = 2.5;
    tic
    sz=size(A);
    [xx yy] = meshgrid(1:sz(2), 1:sz(1));
    center = round(sz/2);
    centerPoints = find((xx - center(1)).^2 + (yy - center(2)).^2  < radius.^2);
    centerIndex = sub2ind(sz, center(1), center(2));
    
    % limit to just the points that are "far enough on the inside":
    inside = find(xx > radius+1 & xx < sz(2) - radius & ...
        yy > radius + 1 & yy < sz(1) - radius);
    
    offsets = centerPoints - centerIndex;
    allPoints = 1:prod(sz);
    insidePoints = allPoints(inside);
    indices = bsxfun(@plus, offsets, insidePoints);
    
    hh = histc(A(indices), 0:0.1:1);  % <<<< modify to give you the histogram you want
    toc
    

    关于performance - Matlab:圆形邻域内局部直方图的高效计算,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21750989/

    10-13 01:08