I have a series of small images, stored as 2d numpy arrays. After applying a threshold, I turn the input image into a masked array (mask out values below threshold). Based on this, as shown in the plot below I end up with a number of different objects (2 sometimes more). How can I identify the object that is nearest to center of this masked image, and return an array containing only that object?
img = masked_array(
data=[[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, 1.0, 1.0, --, --, --, --,
--, --, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, 1.0, 1.0, 1.0, --, --, --, --,
--, --, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, 1.0, 1.0, 1.0, --, --, --, --,
--, --, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, 1.0, 1.0, --, --, --, --,
--, --, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, 1.0, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, 1.0, 1.0, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, 1.0, 1.0, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, 1.0, 1.0, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --],
[--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --, --, --, --, --, --, --, --, --,
--, --, --, --, --, --, --, --]],
mask=[[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, False, False,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, False, False, False,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, False, False, False,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, False, False,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, False, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, False, False, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, False, False, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, False, False, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True],
[ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True]],
fill_value=1e+20)
Getting indices of non masked point to get the one closest to the center
>>> center = [[img.shape[1] // 2, img.shape[0] // 2]]
>>> center
[[20, 20]]
>>> indices = np.array(list(zip(*img.nonzero())))
>>> indices
array([[18, 25],
[18, 26],
[19, 24],
[19, 25],
[19, 26],
[20, 24],
[20, 25],
[20, 26],
[21, 25],
[21, 26],
[22, 19],
[23, 19],
[23, 20],
[24, 19],
[24, 20],
[25, 19],
[25, 20]], dtype=int64)
Compute the distance. I'll use scipy for this
>>> from scipy.spatial.distance import cdist
>>> distance = cdist(indices, center)
>>> distance
array([[5.38516481],
[6.32455532],
[4.12310563],
[5.09901951],
[6.08276253],
[4. ],
[5. ],
[6. ],
[5.09901951],
[6.08276253],
[2.23606798],
[3.16227766],
[3. ],
[4.12310563],
[4. ],
[5.09901951],
[5. ]])
>>> np.argmin(distance)
10
>>> distance[10]
array([2.23606798])
>>> closest_point = indices[10]
>>> closest_point
array([22, 19], dtype=int64)
Find the "object" ( = the connected component) closest to the center.
I'll use OpenCV for this
>>> import cv2
>>> N_cc, cc = cv2.connectedComponents(img.data.astype(np.uint8))
>>> N_cc
3 # 3 objects on your image: the 2 'black' and the white one
>>> obj = np.array(
list(zip(
*np.where(cc == cc[closest_point[0], closest_point[1]]) # getting all the points from the connected component having the same label as the point closest to the center
))
)
>>> obj
array([[22, 19], # the closest point to the center
[23, 19], # and all its neighbours in the same object
[23, 20],
[24, 19],
[24, 20],
[25, 19],
[25, 20]], dtype=int64)
Keep only the main object in the original image
>>> img.mask.fill(True)
>>> img.mask[obj[:, 0], obj[:, 1]] = False # numpy version of: for i in obj: img.mask[i[0], i[1]] = False
>>> img.nonzero()
(array([22, 23, 23, 24, 24, 25, 25], dtype=int64),
array([19, 19, 20, 19, 20, 19, 20], dtype=int64))