寻找图像中的质心
Finding the center of mass in an image
这是我的图片:
我想找到这张图片的重心。我可以通过绘制两条垂直线来找到质心的大致位置,如下图所示:
我想使用python中的图像处理工具找到它。我对 python (scikit-image) 的图像处理库有一点经验,但是,我不确定这个库是否可以帮助找到我图像中的质心。
我想知道是否有人可以帮助我做到这一点。如果可以使用 python 中的任何其他库在我的图像中找到质心,我会很高兴。
预先感谢您的帮助!
您需要了解 Image Moments。
Here 有一个关于如何将它与 opencv 和 python
一起使用的教程
skimage.measure.regionprops
会为所欲为。这是一个例子:
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)
在我的机器上和你的示例图像中,我得到 (228.48663375508113, 200.85290046969845)
。
我们可以拍出漂亮的照片:
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()
这给了我这个输出:
您会注意到有一些您可能不想要的前景,例如图片的右下角。这是一个完全不同的答案,但您可以查看 scipy.ndimage.label
、skimage.morphology.remove_small_objects
,更一般地查看 skimage.segmentation
。
您可以使用 scipy.ndimage.center_of_mass 函数找到物体的质心。
例如使用本题图片:
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
这是我的图片:
我想找到这张图片的重心。我可以通过绘制两条垂直线来找到质心的大致位置,如下图所示:
我想使用python中的图像处理工具找到它。我对 python (scikit-image) 的图像处理库有一点经验,但是,我不确定这个库是否可以帮助找到我图像中的质心。 我想知道是否有人可以帮助我做到这一点。如果可以使用 python 中的任何其他库在我的图像中找到质心,我会很高兴。 预先感谢您的帮助!
您需要了解 Image Moments。
Here 有一个关于如何将它与 opencv 和 python
一起使用的教程skimage.measure.regionprops
会为所欲为。这是一个例子:
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)
在我的机器上和你的示例图像中,我得到 (228.48663375508113, 200.85290046969845)
。
我们可以拍出漂亮的照片:
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()
这给了我这个输出:
您会注意到有一些您可能不想要的前景,例如图片的右下角。这是一个完全不同的答案,但您可以查看 scipy.ndimage.label
、skimage.morphology.remove_small_objects
,更一般地查看 skimage.segmentation
。
您可以使用 scipy.ndimage.center_of_mass 函数找到物体的质心。
例如使用本题图片:
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