python - 如何在 Python 中使用图像处理找到物体的直径?

标签 python numpy image-processing geometry ndimage

给定一张包含一些不规则物体的图像,我想求出它们各自的直径。

Thanks to this answer ,我知道如何识别对象。 但是,是否可以测量图像中显示的物体的最大直径?

我查看了 scipy-ndimage 文档,但没有找到专门的函数。

对象识别代码:

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

图片: enter image description here

最佳答案

你可以使用 skimage.measure.regionprops确定图像中所有区域的边界框。对于大致圆形的 Blob ,最小外接圆的直径可以近似为边界框的最大边。为此,您只需在脚本末尾添加以下代码段:

from skimage.measure import regionprops

properties = regionprops(labels)
print 'Label \tLargest side'
for p in properties:
    min_row, min_col, max_row, max_col = p.bbox
    print '%5d %14.3f' % (p.label, max(max_row - min_row, max_col - min_col))

fig = plt.figure()
ax = fig.add_subplot(111)    
ax.imshow(np.ma.masked_array(labels, ~blobs), cmap=plt.cm.gist_rainbow) 
ax.set_title('Labeled objects')
plt.xticks([])
plt.yticks([])
for ri, ci, li in zip(r, c, range(1, nlabels+1)):
    ax.annotate(li, xy=(ci, ri), fontsize=24)
plt.show()

这是你得到的输出:

Label   Largest side
    1        106.000
    2         75.000
    3         79.000
    4         56.000
    5        161.000
    6         35.000
    7         47.000  

Labeled objects

关于python - 如何在 Python 中使用图像处理找到物体的直径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38598690/

相关文章:

python - 使用 Dataframe 来识别 session

python - OpenCV 如何对矩形进行分组

python - 在Python中迭代二维数组?

c# - 频域中的 Gabor 滤波器实现

python - 记录 mpi4py 子文件

python - Sendgrid 外发电子邮件将显示在我的已发送邮箱中

python - 用 pandas 计算列的 "energy"

python - 在另一个列表中编码列表元素存在的最有效方法

python - numpy.interp 和屏蔽数组

c++ - 如何对 opencv 中的鱼眼图像生成的图像进行去扭曲处理?