简体   繁体   中英

Calculating the center of mass of a binary image (openCV Python)

I study mechanical engineering and this was one of the first programming tasks that I had to do so my coding experience especially in python and open cv was almost zero when I started this.

We were given a picture and should write a program to calculate the center of mass of the shape.

Here is the code that I came up with,

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('C:/Amoebe/Amoebebesser.png',0)
img = cv2.medianBlur(img,5)
ret,th1 = cv2.threshold(img,100,255,cv2.THRESH_BINARY)
plt.imshow(th1, cmap = 'gray', interpolation = 'none')
plt.show()

momentx = 0
momenty = 0
count = 0

for i in range(th1.shape[0]):
    for j in range(th1.shape[1]):
        if th1[i, j] >= 255:
            momentx = momentx + j
            momenty = momenty + i
            count = count + 1

centx = int(momentx / count)
centy = int(momenty / count)
print(centx)
print(centy)
cv2.circle(th1, (centy, centx), 1, (0, 0, 255), 2)
cv2.imshow('image', th1)
k = cv2.waitKey(0)
if k == 27:         # wait for ESC key to exit
    cv2.destroyAllWindows()
elif k == ord('s'): # wait for 's' key to save and exit
    cv2.imwrite('centerofmasstest.png', th1)
    cv2.destroyAllWindows()

From what I have read there is a lot of optimizing that could be done using numpy but I couldn't figure out how to do it. Also, I am not sure if I am actually getting the center of mass or if there are errors in my method.

Thank you very much in advance for your time and best regards.

We can use np.where and np.average to do this easily.

# Find indices where we have mass
mass_x, mass_y = np.where(th1 >= 255)
# mass_x and mass_y are the list of x indices and y indices of mass pixels

cent_x = np.average(mass_x)
cent_y = np.average(mass_y)

EDIT: Oneliner
center = [ np.average(indices) for indices in np.where(th1 >= 255) ]

your code looks correct. I might leave the int(...) off to get a subpixel resolution centroid value. the coordinate (0.0, 0.0) would be the center of the top left pixel.

apart from the numpy solution, there is cv2.moments , which can be run on contours and mask images directly, and it gives you various moment values (m00, m10, m01, ...) you can use to calculate the centroid (m10/m00, m01/m00)

m00 is count, m10 is momentx, m01 is momenty.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM