7

Here is my image: enter image description here

I want to find the center of mass in this image. I can find the approximate location of the center of mass by drawing two perpendicular lines as shown in this image: enter image description here

I want to find it using an image processing tool in python. I have a little experience in the image processing library of python (scikit-image) but, I am not sure if this library could help finding the center of mass in my image. I was wondering if anybody could help me to do it. I will be happy if it is possible to find the center of mass in my image using any other library in python. Thanks in advance for your help!

Avi Olan
  • 61
  • 1
  • 11
Leo
  • 479
  • 2
  • 6
  • 16
  • Stack Overflow is not a site where you can put requests for code. – Jongware Feb 20 '18 at 18:47
  • 2
    Request a code?! Please read my question carefully and let me know where I requested a code. I just asked for help. – Leo Feb 20 '18 at 19:05
  • 2
    It sounds like you are looking for `skimage.measure.moments` (http://scikit-image.org/docs/dev/api/skimage.measure.html) – Stefan van der Walt Feb 20 '18 at 20:43
  • I took a look at it but I did not get it right. Is it possible to provide a very simple example for example finding the enter of a square or circle in an image so I can learn how to implement it in my image? – Leo Feb 21 '18 at 02:10

3 Answers3

26

skimage.measure.regionprops will do what you want. Here's an example:

import imageio as iio
from skimage import filters
from skimage.color import rgb2gray  # only needed for incorrectly saved images
from skimage.measure import regionprops

image = rgb2gray(iio.imread('eyeball.png'))
threshold_value = filters.threshold_otsu(image)
labeled_foreground = (image > threshold_value).astype(int)
properties = regionprops(labeled_foreground, image)
center_of_mass = properties[0].centroid
weighted_center_of_mass = properties[0].weighted_centroid

print(center_of_mass)

On my machine and with your example image, I get (228.48663375508113, 200.85290046969845).

We can make a pretty picture:

import matplotlib.pyplot as plt
from skimage.color import label2rgb

colorized = label2rgb(labeled_foreground, image, colors=['black', 'red'], alpha=0.1)
fig, ax = plt.subplots()
ax.imshow(colorized)
# Note the inverted coordinates because plt uses (x, y) while NumPy uses (row, column)
ax.scatter(center_of_mass[1], center_of_mass[0], s=160, c='C0', marker='+')
plt.show()

That gives me this output:

eye center of mass

You'll note that there's some bits of foreground that you probably don't want in there, like at the bottom right of the picture. That's a whole nother answer, but you can look at scipy.ndimage.label, skimage.morphology.remove_small_objects, and more generally at skimage.segmentation.

Juan
  • 5,433
  • 21
  • 23
4

You can use the scipy.ndimage.center_of_mass function to find the center of mass of an object.

For example, using this question's image:

wget https://i.stack.imgur.com/ffDLD.jpg
import matplotlib.image as mpimg
import scipy.ndimage as ndi

img = mpimg.imread('ffDLD.jpg')
img = img.mean(axis=-1).astype('int')  # in grayscale

cy, cx = ndi.center_of_mass(img)

print(cy, cx)
228.75223713169711 197.40991592129836
ldavid
  • 2,512
  • 2
  • 22
  • 38
0

You need to know about Image Moments.

Here there's a tutorial of how use it with opencv and python

Moia
  • 2,216
  • 1
  • 12
  • 34
  • 4
    please add some information to your answer. just providing links will render your answer useless once the links are dead. – Piglet Feb 20 '18 at 15:59