I have a grey scale image and would like to find the centre of mass (centre of intensity) of this image. I don't want to find the mean value across of each axis.
So I have a 2D array which represents the intensity of this image along the horizontal and vertical axis. The centre of mass is obviously where the white dot is but i don't manage to find a way to calculate it's coordinates.
The results I obtain are always wrong.[My results are 750 along the horizontal line and 454 along the vertical. The white dot centre coordinates are 520 along the horizontal axis and 430 along the vertical !
Here is what I tried :
img
is the 2D array which represents the intensity of this image. Its a 1024 row, 1280 columns array. How can i find the centre of mass of this image pls ?
intensite_total = np.sum(img)#This contains the sum of each element from the img matrix
X = np.linspace(0,1023,1024)
print(X)
print(np.shape(X))
print(np.shape(X))
x_bary = np.sum(np.dot(X,img))/intensite_total
print(x_bary)
print("YYYYYYYYYYYYYY")
Y = np.linspace(0,1279,1280)
print(Y)
print(np.shape(Y))
print(np.shape(np.dot(img,Y)))
y_bary = np.sum(np.dot(img,Y))/intensite_total
print(y_bary)
The center of mass is found by computing its integral. For this you need two coordinate arrays, weight the data with the coordinate arrays and sum:
import numpy as np
image = np.random.random((100, 200))
x = np.arange(image.shape[1])
y = np.arange(image.shape[0])
xx, yy = np.meshgrid(x, y)
A = image.sum()
# Center of mass
x_cms = (xx * image).sum() / A
y_cms = (yy * image).sum() / A
print(x_cms, y_cms)
Which prints:
99.30012423254516 49.62527469708466
UPDATE:
I double checked and this gives the same result as your code:
A = np.sum(image)
X = np.linspace(0, image.shape[1] - 1, image.shape[1])
x_cms = np.sum(np.dot(image, X)) / A
Y = np.linspace(0, image.shape[0] - 1, image.shape[0])
y_cms = np.sum(np.dot(Y, image)) / A
print(x_cms, y_cms)
Which prints:
99.30012423254516 49.62527469708466
UPDATE 2:
I took a closer look at the data and plotting on logarithmic scale, one can see that the background is not empty:
A simple threshold of the data like image[image < 20] = 0
, leads to the expected result:
521.9619304953782 430.8132321823475
I hope this helps!