3

I've got a heat map numpy array with shape (600,400). The heatmap represents probabilities of detection. In my case, the probability of face detections in an image. My goal is to take this heatmap and get the coordinates (X and Y) where the highest probability occurs.

I've solved this for the case of a single face. The code for that is the following:

face_location = np.unravel_index(heatmap.argmax(), heatmap.shape)
    print("Face location: " + str(face_location))

But in some cases there are multiple faces. I don't know how to adjust the algorithm to return multiple "hottest area". The issue is that any one hot area will be surrounded by gradually less hot areas. And so it's possible that after the hottest area, the next top 10 will all be right beside the initial point.

How can I adjust the algorithm to look for multiple hot areas? It's ok to assume that they won't be right beside each other.

heatmap = [[  2.00299415e-04   2.03753079e-04   8.17560707e-04 ...,   2.23556344e-04
         1.98958180e-04   9.92935777e-01]
      [  2.00642273e-04   2.04473894e-04   8.19963054e-04 ...,   2.24148811e-04
         1.99438742e-04   9.92921114e-01]
      [  2.01056406e-04   2.05344462e-04   8.22864589e-04 ...,   2.24864416e-04
         2.00019145e-04   9.92903233e-01]
      ..., 
      [  7.28193991e-05  -2.73474743e-05   2.95096161e-05 ...,   5.96550672e-05
         1.98282614e-05   9.99637246e-01]
      [  7.34055429e-05  -2.72389279e-05   3.02382941e-05 ...,   5.98490733e-05
         2.04356711e-05   9.99619305e-01]
      [  7.37556256e-05  -2.71740992e-05   3.06735128e-05 ...,   5.99649393e-05
         2.07984649e-05   9.99608397e-01]]
megashigger
  • 8,695
  • 17
  • 47
  • 79
  • Might want to have a look at [How to get indices of N maximum values in a numpy array?](https://stackoverflow.com/questions/6910641/how-to-get-indices-of-n-maximum-values-in-a-numpy-array) if I'm reading your question correctly. – Brad Solomon Oct 15 '17 at 01:55

2 Answers2

0

Perhaps consider using a mask array with a threshold probability defining the hot areas?

In [29]: threshold_probability = 0.8

In [30]: prng = np.random.RandomState(42)

In [31]: heatmap = prng.rand(600, 400)

In [32]: heatmap
Out[32]: 
array([[ 0.37454012,  0.95071431,  0.73199394, ...,  0.42899403,
         0.75087107,  0.75454287],
       [ 0.10312387,  0.90255291,  0.50525237, ...,  0.56513318,
         0.69665082,  0.92249938],
       [ 0.70723863,  0.15253904,  0.57628836, ...,  0.96887786,
         0.74965183,  0.13008624],
       ..., 
       [ 0.77669933,  0.98757844,  0.72686576, ...,  0.149866  ,
         0.6685433 ,  0.90248875],
       [ 0.116007  ,  0.96352904,  0.33109138, ...,  0.85776718,
         0.88838363,  0.00901272],
       [ 0.30810176,  0.43190563,  0.60935151, ...,  0.07498895,
         0.60716006,  0.31712892]])

In [33]: hottest_areas = np.ma.MaskedArray(heatmap, heatmap < threshold_probability)

In [34]: X, Y = hottest_areas.nonzero()

In [35]: X
Out[35]: array([  0,   0,   0, ..., 599, 599, 599])

In [36]: Y
Out[36]: array([  1,   7,  11, ..., 376, 388, 394])

The result is a tuple containing the x and y coords of the values for which the boolean condition defining the mask is False (i.e., areas for which the probability of face is higher than threshold).

davidrpugh
  • 4,363
  • 5
  • 32
  • 46
0

If you want to go with a threshold like davidrpugh proposed I have a different approach to propose. Instead of finding the non zero elements, just find the connexe components of your binary image.

import numpy as np
from scipy.ndimage.measurements import label
from skimage.measure import regionprops

heatmap = np.random.rand(100, 25)

thresh = 0.9
bw = np.array(heatmap)
bw[bw < thresh] = 0

img_cc, nb_cc = label(bw)
cc = regionprops(img_cc)

face_location = np.array([c.centroid for c in cc])

import matplotlib.pyplot as plt

plt.figure()
plt.imshow(heatmap)
plt.plot(face_location[:, 1], face_location[:, 0], 'r*')

plt.figure()
plt.imshow(img_cc)
plt.plot(face_location[:, 1], face_location[:, 0], 'r*')

plt.show()

The face location are here defined by the centers of the connexe components but you can look for the maximum of each region in the image instead.