如何在Python中使用图像处理来查找对象的直径? [英] How to find the diameter of objects using image processing in Python?

查看:966
本文介绍了如何在Python中使用图像处理来查找对象的直径?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个带有一些不规则物体的图像,我想找到它们各自的直径。

解决方案

您可以使用 skimage.measure.regionprops 来确定图像中所有区域的边界框。对于大致圆形的斑点,最小包围圆的直径可以通过边界框的最大边来近似。为此,您只需在脚本末尾添加以下片段:

  from skimage.measure import regionprops 

属性= regionprops(标签)
print'Label \Largest side'
用于属性p:
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,〜blob),cmap = plt.cm.gist_rainbow)
ax.set_title('Labeled objects')
plt .bicks([])
plt.yticks([])
for ri,ci,li in zip(r,c,range(1,nlabels + 1)):
ax。注释(li,xy =(ci,ri),fontsize = 24)
plt.show()

这是您得到的输出:

 标签最大的一面
1 106.000
2 75.000
3 79.000
4 56.000
5 161.000
6 35.000
7 47.000


Given an image with some irregular objects in it, I want to find their individual diameter.

Thanks to this answer, I know how to identify the objects. However, is it possible to measure the maximum diameter of the objects shown in the image?

I have looked into the scipy-ndimage documentation and haven't found a dedicated function.

Code for object identification:

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

Image:

解决方案

You could use skimage.measure.regionprops to determine the bounding box of all the regions in your image. For roughly circular blobs the diameter of the minimum enclosing circle can be approximated by the largest side of the bounding box. To do so you just need to add the following snippet at the end of your script:

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

And this is the output you get:

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

这篇关于如何在Python中使用图像处理来查找对象的直径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆