# 8 neighbours of a pixel after converting to 1D array

28 views (last 30 days)
zepp on 28 Feb 2013
Edited: Gilles on 25 Mar 2020
Hi
Is there a simple way to access the 8 neighbours of a pixel x(i,j) given by x(i-1,j-1), x(i-1,j), x(i-1,j+1), x(i,j-1), ... ,x(i+1,j+1) after converting x into a 1D array? I have been using for loops to achieve this but it's quite slow if the matrix x is large.
Thanks.

zepp on 28 Feb 2013
I have to run the neighbourhood operation for each pixel in the matrix. I simply use 2 for loops to get the neighbours of each pixel and get the distances. But if I convert the whole matrix into a vector, getting the 8 neighbours for each pixel is not straightforward. I would have to use sub2ind 8 times for each pixel to get the corresponding subscripts of its neighbourhood pixels. This will be quite slow.
Sean de Wolski on 28 Feb 2013
Use the two for-loops on the matrix and keep the column vector also for your column vector needs.
Image Analyst on 28 Feb 2013
Thanks for the clarification. So your question should have read: "access the 8 neighbours of a pixel x(i,j) given by x(i-1,j-1), x(i-1,j), x(i-1,j+1), x(i,j-1), ... ,x(i+1,j+1) and convert them into a 1D array".
Saying "after converting x into a 1D array" was imprecise since you did not have this 1D array yet, and you never converted x - the entire x - into a 1D array.

Jan on 28 Feb 2013
Edited: Jan on 28 Feb 2013
w = 200;
h = 100;
x = rand(h, w);
xv = x(:); % A very fast reshape
pattern = [1,2,3, h+1, h+3, 2*h+1, 2*h+2, 2*h+3];
focus = h + 2;
% Neighborhood of the pixel at position (2,2):
xv(pattern) - xv(focus)
% Next pixel:
pattern = pattern + 1;
focus = focus + 1;
xv(pattern) - xv(focus)
% etc. This would happen in a loop of course.
% Consider the edges: pattern = pattern + 3
I cannot create the required loops, because I do not know the wanted output style.

Sajid Rahim on 16 Oct 2017
clear all;
[filename pathname]=uigetfile('*.jpg;*.png;*.tif;*.tiff;*.gif;*.bmp;');
I=inputimage;
I = rgb2gray(I) ;
[y,x] = find(I) ;
figure
imshow(I)
hold on
plot(x,y,'.b')
% x
% y
% z=(y+x)/2
% plot(z,'.r')
a=x(1)
b=y(1) plot(x(1),y(1),'*y')
plot(x(end),y(end),'*y')
% neighbors(1) = (a,b-1);
neighbors(1) = I(a,b-1);
plot(a,b-1,'*r')
neighbors(2) = I(a,b+1);
plot(a,b+1,'*r')
neighbors(3) = I(a,b+2);
plot(a,b+2,'*r')
neighbors(4) = I(a+1,b);
plot(a+1,b,'*r')
neighbors(5) = I(a+1,b+1);
plot(a+1,b+1,'*r')
neighbors(6) = I(a+2,b+2);
plot(a+2,b+2,'*r')
neighbors(7) = I(a+2,b);
plot(a+2,b,'*r')
neighbors(8) = I(a+2,b+1);
plot(a+2,b+1,'*r')
neighbors(9) = I(a+2,b+2);
plot(a+2,b+2,'*r')
this is my code... i findede the 8 neighbours of a fixel ... now i wan to find again 8 neighbours of ech finded fixels neighbours.. plz help me......
Jan on 17 Oct 2017
@Sajid Rahim: Do not post unrelated code in a thread of someone else, please. Open a new thread for you own problem.
Gilles on 25 Mar 2020
@Jan, Thanks a lot for this usefull code to find neighboor indices of a pixel after converting a matrix into an 1D array.
Do you know the formules to generalize this code for kernel of large size ?
I want to find the neighboors indices for :
• 5x5 kernel --> 24 neighboors
• 7x7 kernel --> 48 neighboors

Image Analyst on 28 Feb 2013
Yes, To access the 3rd element of your 1D array, you do
thirdElement = array1D(3)
Is that what you meant? It seems like what you asked. It does not depend on the size of x obviously, just on the size of the "ring", so a 3x3 window would have 8 elements, a 5x5 would have 18, and so on.

Sean de Wolski on 28 Feb 2013
Edited: Sean de Wolski on 28 Feb 2013
As I mentioned in the comment: I would just reshape the image to its original (or leave it alone) and make a second variable that is the column vector:
x = rand(10000);
x2 = reshape(x,numel(x),1);
Does not require a deep copy of x so the data is only stored in memory once. And reshape of full matrices is up there on the list of the fastest MATLAB functions. You're certainly not paying any penalties to do what I did above.