I am working with a 2D numpy
array made of 101x101=10201
values. Such values are of float
type and range from 0.0
to 1.0
. The array has an X,Y
coordinate system which originates in the top left corner: thus, position (0,0)
is in the top left corner, while position (101,101)
is in the bottom right corner.
This is how the 2D array looks like (just an excerpt):
X,Y,Value
0,0,0.482
0,1,0.49
0,2,0.496
0,3,0.495
0,4,0.49
0,5,0.489
0,6,0.5
0,7,0.504
0,8,0.494
0,9,0.485
I would like to be able to:
1) Count the number of regions of cells (see image below) which value exceeds a given threshold, say 0.3
;
2) Determine the distance between the visual centers of such regions and the top left corner, which has coordinates (0,0)
.
How could this be done in Python 2.7?
This is a visual representation of a 2D array with 2 regions highlighted (the darker the color, the higher the value):
Indexing a Two-dimensional Array To access elements in this array, use two indices. One for the row and the other for the column. Note that both the column and the row indices start with 0. So if I need to access the value '10,' use the index '3' for the row and index '1' for the column.
Using ndenumerate() function to find the Index of value It is usually used to find the first occurrence of the element in the given numpy array.
Index of element in 2D array We can also use the np. where() function to find the position/index of occurrences of elements in a two-dimensional or multidimensional array. For a 2D array, the returned tuple will contain two numpy arrays one for the rows and the other for the columns.
In Python, we can access elements of a two-dimensional array using two indices. The first index refers to the indexing of the list and the second index refers to the position of the elements. If we define only one index with an array name, it returns all the elements of 2-dimensional stored in the array.
You can find which pixels satisfy your cut-off using a simple boolean condition, then use scipy.ndimage.label
and scipy.ndimage.center_of_mass
to find the connected regions and compute their centers of mass:
import numpy as np
from scipy import ndimage
from matplotlib import pyplot as plt
# generate some lowpass-filtered noise as a test image
gen = np.random.RandomState(0)
img = gen.poisson(2, size=(512, 512))
img = ndimage.gaussian_filter(img.astype(np.double), (30, 30))
img -= img.min()
img /= img.max()
# use a boolean condition to find where pixel values are > 0.75
blobs = img > 0.75
# label connected regions that satisfy this condition
labels, nlabels = ndimage.label(blobs)
# find their centres of mass. in this case I'm weighting by the pixel values in
# `img`, but you could also pass the boolean values in `blobs` to compute the
# unweighted centroids.
r, c = np.vstack(ndimage.center_of_mass(img, labels, np.arange(nlabels) + 1)).T
# find their distances from the top-left corner
d = np.sqrt(r*r + c*c)
# plot
fig, ax = plt.subplots(1, 2, sharex=True, sharey=True, figsize=(10, 5))
ax[0].imshow(img)
ax[1].hold(True)
ax[1].imshow(np.ma.masked_array(labels, ~blobs), cmap=plt.cm.rainbow)
for ri, ci, di in zip(r, c, d):
ax[1].annotate('', xy=(0, 0), xytext=(ci, ri),
arrowprops={'arrowstyle':'<-', 'shrinkA':0})
ax[1].annotate('d=%.1f' % di, xy=(ci, ri), xytext=(0, -5),
textcoords='offset points', ha='center', va='top',
fontsize='x-large')
for aa in ax.flat:
aa.set_axis_off()
fig.tight_layout()
plt.show()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With