给出一个带有一些圆形物体(例如硬币)的输入图像(例如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()
我是新来的,所以我不知道怎么玩得很好,此代码生成的图像位于我所基于的问题的链接中。
答案 0 :(得分: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
否则,半径的定义不明确:边界框的大小?最大长度的圆弧?
编辑:我添加了对边框最大尺寸的评估
答案 1 :(得分:0)
您可以使用OpenCV2函数cv2.connectedComponentsWithStats(blobs)
。此函数返回最左边的(x)坐标,它是水平方向上边界框的包含起始点,最上面的(y)坐标是边界内包含的起始位置边框在垂直方向上的大小,边框的水平大小,边框的垂直大小,所连接组件的总面积(以像素为单位)。要使用这些功能,必须转换blobs.dtype='uint8'
。
使用该区域并假设一个完美的圆形对象,您可以计算直径或按照建议使用边界框的大小。