首页 > 解决方案 > 如何在 Python 中使用图像处理来查找输入图像对象的直径?

问题描述

给定一个输入图像,例如带有一些圆形物体(例如硬币)的 jpg,我想找到它们各自的直径。

感谢这个问题(How to find the diameter of objects using image processing in Python?,我知道如何识别物体,但我想测量我插入的图像的直径,而不是用方法随机生成。我该怎么做?

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()

我是新来的,所以我不知道如何玩得很好,这段代码生成的图像在我所在问题的链接中。

标签: pythonnumpyimage-processinggeometryndimage

解决方案


一个简单的近似可以是假设完美的圆形物体,那么半径是面积的平方根(即像素数)除以 pi:

def radius(A):
    return np.sqrt( A/np.pi )

def max_bounding_box(labels, k):
    idx, idy = np.where( labels==k )
    Sx = max(idx) - min(idx)
    Sy = max(idy) - min(idy)
    return max(Sx, Sy)/2

for k in range(1, nlabels):
    A = len( np.nonzero( labels==k )[0] )
    print(k, radius(A), max_bounding_box(labels, k)


1 41.32472068116174 52.5
2 31.040683392579073 37.0
3 34.37391885593249 39.0
4 26.986904594423443 27.5
5 73.79677393164606 80.0
6 15.012108426804138 17.0

否则,半径定义不明确:边界框的大小?最大长度的弧?

编辑:我添加了边界框最大尺寸的评估


推荐阅读