Home > Back-end >  find index of biggest values in 2d-Numpy array only in selected region
find index of biggest values in 2d-Numpy array only in selected region

Time:09-09

I have a 2 dimensional Numpy array that contains values. I need to find the index of biggest 100 values in a given slice of the array. The problem is, that the index of the values, must be relative to the whole image, not relative to the slice.

So, if my array is 255 x 255, and has random values ranging from 1 to 12000.

I need to know what are the 100 biggest values in the range [120:120,160:160]. But its coordinates/indexes must be relative to the whole array, not the slice.

for example

   [1, 1, 1, 2]
   [1, 1, 3, 2]
   [9, 9, 9, 2]
   [9, 9, 9, 2]

Lets say that in above example, my slice is the 4 central values. (1,3,9,9) and I want the index of the 3 biggest values in this slice. The result should be: [1:2, 2:1, 2:2] as these are the absolute indexes of the values 3,9,9 that are the 3 biggest of my slice.

I tried by extracting the slice, flattening it, and using argpartition, but that gave me the index relative to the slice, and not relative to the whole array.

This is what I tried:

            depthRoi = depthFrame[top:bottom, left:right]
            depthRoiFlat = depthRoi.flatten()
            ind = np.argpartition(depthRoiFlat, -1000)[-1000:]

DepthFrame is the whole array. depthRoi is my slice of interest, and ind, is the extracted index of the 1000 biggest values of my slice. The index is relative to the ROI, not the whole array tough..

How can this be done?

Thank you

CodePudding user response:

To Find the first n max values in sub-block

a = np.random.rand(255,255) ## some random array

n_sort = 10 ## number of first n max values

block_start = [20,50] ## block starting corner

slice_arr = a[block_start[0]:100,block_start[1]:90] ## your slice

idx_slice = np.argpartition(slice_arr.reshape(-1), -n_sort)[-n_sort:] ## sort the slice

idx_req = np.zeros((n_sort,2),dtype=int) ## create a array to store indices

q_rem = np.divmod(idx_slice,slice_arr.shape[1]) ## for a A[m,n] array, 
## contd. A[i,j] corresponds to i*n j element in flatten array. so you get i,j from quotient and reminder of flattened index when divided by n

## You can also use np.unravel_index
## q_rem = np.unravel_index(idx_slice,shape=slice_arr.shape)

idx_req[:,0] = block_start[0]   q_rem[0]
idx_req[:,1] = block_start[1]   q_rem[1]


CodePudding user response:

Variant using unravel_index on the original OP code

top, bottom, left, right = 1, 3, 1, 3
N = 3

depthRoi = depthFrame[top:bottom, left:right]
depthRoiFlat = depthRoi.flatten()
ind = np.argpartition(depthRoiFlat, -N)[-N:]

out = np.c_[np.unravel_index(ind, (bottom-top, right-left))]   [top, left]

output:

array([[1, 2],
       [2, 1],
       [2, 2]])

As lists of coordinates:

tuple(out.T)

output: (array([1, 2, 2]), array([2, 1, 2]))

  • Related