0

I have an array of linear indices and for each linear index, I want to find the linear indices of the neighboring pixels in a radius of let's say 5-pixels. I found the following code which does the job for a 8-connected neighborhood. But, how to implement it to find the linear indices of 120 neighbors for a 5-pixel neighborhood.

%# target_array: array where pixels are marked
%# idx: linear index of a marked pixel
[M,N] = size(target_array)

neighbor_offsets=[-M-1 -M -M+1 1 M+1 M M-1 -1];

neighbors = bsxfun(@plus, idx, neighbor_offsets);
Jonas
  • 74,690
  • 10
  • 137
  • 177
Umar Asif
  • 111
  • 1
  • 9

2 Answers2

1

The code you mention finds the linear indices around a pixel, as long as the pixel is not too close to the border of the target array.

In your case, I suggest you loop through the pixels individually, and find the neighborhood:

[M,N] = size(target_array);

SE = strel('disk',5,inf);

%# the linear indices are stored in idxList
nIndices = length(idxList);

neighbors = cell(nIndices);

for ii = 1:nIndices
    idx = idxList(ii);
    bw = false(M,N);
    bw(idx) = true;
    bw = imdilate(bw,SE);

    %# mask the center
    bw(idx) = false;

    neighbors{ii} = find(bw);
end

If you know that none of the neighborhoods overlap or touch, you can simplify the above:

bw = false(M,N);
bw(idxList = true;
bw = imdilate(bw,SE);
bw(idxList) = false;
cc = bwconncomp(bw);
neighbors = cc.PixelIdxList;
Jonas
  • 74,690
  • 10
  • 137
  • 177
  • Thanks for the help. I've got more than 90k entries in the idx array to process. This for-loop approach is very expensive. Yes, the neighborhoods do overlap. Is there any loop-free efficient way to process the entire idx list in less than a sec? – Umar Asif Apr 30 '13 at 03:29
0

You can do it with meshgrid and sub2ind

Assuming a target array called T and index points(m, n) where [m, n] = ind2sub(size(T), ind);

[X, Y] = meshgrid(m-5:m+5, n-5:n+5);
I = sub2ind(size(T), X(:), Y(:));

But if you are worried about the edges (which you should be) then use min and max as follows:

[M, N] = size(T);
[X, Y] = meshgrid(max(1,m-5):min(M,m+5), max(1,n-5):min(N,n+5));
I = sub2ind(size(T), X(:), Y(:));

Also note that this will include the center point, but that;s easy to remove by finding it's linear index using sub2ind(size(T), m, n);

Dan
  • 45,079
  • 17
  • 88
  • 157
  • thanks for your code Dan! I'm trying to optimize a function that is taking to much time to compute and it's based on circular neighboorhoods. More precisely, I've different circular neighboorhoods and inside of each of them, I want to compute the mean, std, and median of the pixel values underlying them. This is done in the context of the DoG scale representation. The size of the circular filter is given by radius associated at a specific scale (`scalespace_radii`): http://pastebin.com/WkS5ShMf Any suggestion on how to improve the computation is welcomed! – Tin Feb 11 '14 at 22:57
  • @Tin Please post this as a new question – Dan Feb 12 '14 at 06:21
  • thanks Dan! I posted it already as a new question :-) http://stackoverflow.com/questions/21724404/matlab-optimizing-code-for-computing-statistics-in-multi-scale-circular-neighbo – Tin Feb 12 '14 at 10:00