1

I am trying to create a neighborhood of pixel by using pixel matrix. The pixel matrix is the matrix of pixels in a 1 band image. Now I have to form matrix of 3*3 keeping each element of 9*9 matrix at center and have a neighbor for each element. Thus the element at (0,0) position will have neighboring elements as

[[0 0 0],
 [0 2 3],
 [0 3 4]] 

Same case will happen to all elements in the first and last row and column. Attached image can help understanding better.

So the resultant matrix will have the size of 81*81. It is not necessary to save the small matrix in the form of matrix.

I have tried below,

n = size[0]
z= 3
x=y=0
m =0

while all( [x<0, y<0, x>=n, y>=n]):
    continue
else:
    for i in range(0, n):
        arcpy.AddMessage("Hello" ) 
        for x in range(m,m+3):
            temp_matrix = [ [ 0 for i in range(3) ] for j in range(3) ]
            for y in range(m,m+3):
                temp_matrix[x][y] = arr_Pixels[x][y]
                m+=1
            y+=1

            temp_List.append(temp_matrix)

But I am getting error: list assignment out of index. Also it looks too lengthy and confusing. I understood the error is occurring because, there is no increment in the array temp_matrix length.

Is there any better way to implement the matrix in image? Smaller matrices can be saved into list rather than matrix. Please help me.

Update #2

n = size[0]
new_matrix = [] 
for i in range(0,n):
    for j in range(0,n):
        temp_mat = [ [ 0 for k in range(3) ] for l in range(3) ]
        for k in range(i-1, i+2):
            for l in range(j-1,j+2):
                if any([k<0, l<0, k>n-1, l>n-1]):
                    temp_mat[k][l] = 0
                else:
                    temp_mat[k][l] = arr_Pixels[k][l]

        new_matrix.append(temp_mat)
AN_SH
  • 217
  • 2
  • 7
  • 16

2 Answers2

0

I think one issue is your use of while/else. The code in else only executes after the while condition is true and the while will not repeat again. This question might be helpful.

Thus, once it enters else, it will never check again that x<=n and y<=n, meaning that x and y can increase beyond n, which I assume is the length of arr_Pixels.

One better way to do it would be to create two nested for loops that increment from 0 to n and create the temp neighborhood matrices and add them to the 9x9 matrix. Here is an rough outline for that:

new_matrix = [] //future 9x9 matrix
for i in range(0, n):
    for j in range(0, n):
         // create a neighborhood matrix going around (i, j) 
         // add temp matrix to new_matrix

This method would avoid having to check that the indexes you are accessing are less than n because it assures that i and j will always be less than n-3.

s.py
  • 197
  • 10
  • can you please elaborate this part // create temp matrix going from (i, j) to (i+3, j+3) of arr_Pixels I tried this n = size[0] new_matrix = [] for i in range(0, n-3): for j in range(0, n-3): # create temp matrix going from (i, j) to (i+3, j+3) of arr_Pixels temp_matrix = [] for i,j in range(i+3,j+3): temp_matrix[i][j] = arr_Pixels[i][j] new_matrix.append(temp_matrix) , but it looks incorrect. @s.py – AN_SH Mar 14 '16 at 22:20
  • I don't how to add indented comments. please check. @s.py – AN_SH Mar 14 '16 at 22:23
  • If the approach with n-3 is followed, it will not create the matrix for the last column element as well as first. Even I need first element to be considered in the center. Like from image, for first element 2, I should get |0 0 0|,|0 2 3|,|0 3 4|. @s.py – AN_SH Mar 14 '16 at 22:46
  • Looking over this, it looks like it should be from (i, j) to (i+2, j+2) instead. I edited my answer to reflect that. – s.py Mar 14 '16 at 23:24
  • I'm not totally sure I understand your 3rd comment? I don't see a matrix of |0 0 0|,|0 2 3|,|0 3 4| in your image. Where should that go? – s.py Mar 14 '16 at 23:26
  • But yes, your first comment is approximately what I am thinking, if you use +2 instead of +3 instead so there will be 3 total elements (rather than 4) – s.py Mar 14 '16 at 23:27
  • Referring to 3rd comment: Yes there are no zeros. I will explain. I am trying to create a neighborhood of pixel by using pixel matrix. The pixel matrix is the matrix of pixels in a 1 band image. Now I have to form matrix of 3*3 keeping each element of 9*9 matrix at center and have a neighbor for each element. Thus the element at (0,0) position will have neighboring elements as |0 0 0|,|0 2 3|,|0 3 4|. I cannot draw a proper matrix here. Same case will happen to all elements in the first and last row and column. In the image, I started from position (2,2). It was my mistake.@s.py – AN_SH Mar 15 '16 at 03:43
  • But I need to start from(0,0). I also tried implementing your logic, but since I have to form 3*3 matrix and loops run for the size of big matrix which 9*9, its not working. Any help would really be appreciated. @s.py – AN_SH Mar 15 '16 at 03:43
  • I think you would use a logic similar to the logic in my answer, but go all the way up to `n` instead of `n-3`. The neighbors of an element at `(i, j)` of a matrix `mat` are `mat[i-1][j]`, `mat[i-1][j-1]`, `mat[i][j-1]`, etc, all around the circle, unless i or j are 0 or n, in which case you substitute 0s. Does that help? Can you update your question to reflect what you have explained to me? – s.py Mar 15 '16 at 03:53
  • I have updated the question. I still have a confusion to limit the small matrix to 3*3, as the loop run for n times. can you help me with that. here is algo i changes, please suggest me the changes.@s.py – AN_SH Mar 15 '16 at 04:14
  • for i in range(0,n): for j in range(0,n): – AN_SH Mar 15 '16 at 04:14
  • I am not able to put the logic for circle of neighbor i.e. mat[i-1][j], mat[i-1][j-1], mat[i][j-1] limiting it to 3*3 matrix. Kindly help. @s.py for i in range(0,n): for j in range(0,n): if(i<0,j<0, i>n-1, j>n-1): temp[i][j] = 0 else: temp[i][j] = arr_Pixels[i-1][j-1] – AN_SH Mar 15 '16 at 04:22
  • Please check above comment. @s.py – AN_SH Mar 15 '16 at 04:22
  • i and j will never be <0 or >n-1. Try `i<0,j<0, i>n-1, j>n-1` – s.py Mar 15 '16 at 12:52
  • Yes, I have added the same condition in above algo too. in if(i<0,j<0, i>n-1, j>n-1), but I am stuck at point where I have to form 3* 3. Since the i & j loops for 9 times, I am not able to form a 3*3 matrix. @s.py – AN_SH Mar 15 '16 at 16:20
  • I have added an update to question. please see Update #2. I believe the logic should work, but I am getting an error IndexError: list assignment index out of range. I understood why is it happening as in temp_mat there is no negative index. but I need help resolving error, how do I save the contents in temp_mat. @s.py – AN_SH Mar 15 '16 at 17:20
  • Please look into updated code Update#2 in the question. @s.py – AN_SH Mar 15 '16 at 18:51
0

I found better way of doing it by padding the whole matrix by zero. Thus it resolves the negative indexing problems. matrix can be padded as

    pixels = np.pad(arr_Pixels, (1,1), mode='constant', constant_values=(0, 0))

It adds rows and columns of zeros along the axes.

AN_SH
  • 217
  • 2
  • 7
  • 16