1

给定一个输入图像,例如带有一些圆形物体(例如硬币)的 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()

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

4

2 回答 2

0

一个简单的近似可以是假设完美的圆形物体,那么半径是面积的平方根(即像素数)除以 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

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

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

于 2018-07-27T08:17:47.973 回答
0

您可以使用 OpenCV2 函数cv2.connectedComponentsWithStats(blobs)。此函数返回最左边 (x) 坐标,它是边界框在水平方向上的包含起点,最上面 (y) 坐标是边界框在垂直方向上的包含起点,边界框的水平尺寸,边界框的垂直尺寸,连接组件的总面积(以像素为单位)。要使用这些功能,您必须转换blobs.dtype='uint8'。使用该区域并假设一个完美的圆形对象,您可以计算直径,或者按照建议使用边界框的大小。

于 2018-07-27T08:22:02.237 回答