首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何利用DipLib测量分割图像的平均厚度

如何利用DipLib测量分割图像的平均厚度
EN

Stack Overflow用户
提问于 2022-09-21 23:38:48
回答 1查看 130关注 0票数 0

我试图测量平均厚度的分割和标记的图像。根据@CrisLuengo的建议,由于我未能成功地使用opencv,所以我转而使用diplib。我在这里找到了一个测量零件厚度的好例子,Measuring the distance between two lines using DipLib (PyDIP)

问题:我可以让这段代码正常工作,并为我的图像的一个片段找到一个估计值,但是第二个片段的代码正在返回错误。以下是我所做的事:

在导入图像并进行一些预处理之后,我最终得到了这个图像:

在这里,我对三种平均厚度感兴趣:

长而窄的白色部分的

  1. 厚度,顶部的
  2. 厚度,

黑色区域的厚度,中厚白色部分的厚度

为了做到这一点,我首先标记了图像,并选择了前2大区域(这是图像的顶部和底部白色部分)。

代码语言:javascript
复制
label_image=measure.label(opening1, connectivity=opening1.ndim)
props= measure.regionprops_table (label_image, properties=['label', "area", "coords"])

slc=label_image
rps=regionprops(slc)
areas=[r.area for r in rps]
id=np.argsort(props["area"])[::-1]
new_slc=np.zeros_like(slc)
for i in id[0:2]:
    new_slc[tuple(rps[i].coords.T)]=i+1

这将产生带有两个标签的标记图像:

由于这里引入的方法只适用于一幅图像,所以我将我的部分分开了。换句话说,我将把重点放在每一个标有标签的部分:

第一个厚白色部件:

代码语言:javascript
复制
slc=label_image
rps=regionprops(slc)
areas=[r.area for r in rps]
id=np.argsort(props["area"])[::-1]
new_slc=np.zeros_like(slc)
for i in id[0:1]:
    new_slc[tuple(rps[i].coords.T)]=i+1

然后运行代码,它返回15.33μm厚度(与实际厚度14.66μm相比,这是一个很好的估计)。它还返回了这个图像。

我不知道如何解释这张图像,但看起来算法是试图显示符合边界的线,现在我想对薄的白色顶部部分做同样的事情。为了做到这一点,我首先选择最上面的白色部分:

代码语言:javascript
复制
rps=regionprops(slc)
areas=[r.area for r in rps]

id=np.argsort(props["area"])[::-1]
new_slc=np.zeros_like(slc)
for i in id[1:2]:
    new_slc[tuple(rps[i].coords.T)]=i+1

然后我运行了这里解释的算法:Measuring the distance between two lines using DipLib (PyDIP)

但是,它返回一个错误。

有人能告诉我,为什么算法不适用于我图像的第二部分?有什么区别,为什么我会犯错?

关于预处理的更新

====================

代码语言:javascript
复制
median=cv2.medianBlur(img,13)
ret, th = cv2.threshold(median, 0 , 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
kernel=np.ones((3,15),np.uint8)
closing1 = cv2.morphologyEx(th, cv2.MORPH_CLOSE, kernel, iterations=2)
kernel=np.ones((1,31),np.uint8)
closing2 = cv2.morphologyEx(closing1, cv2.MORPH_CLOSE, kernel)

label_image=measure.label(closing2, connectivity=closing2.ndim)
props= measure.regionprops_table (label_image, properties=['label'])

kernel=np.ones((1,13),np.uint8)
opening1= cv2.morphologyEx(closing2, cv2.MORPH_OPEN, kernel,  iterations=2)


label_image=measure.label(opening1, connectivity=opening1.ndim)
props= measure.regionprops_table (label_image, properties=['label', "area", "coords"])

原图:下面我展示了我的原始图像的低质量,所以你可以更好地理解为什么我会做所有的预处理。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-23 06:03:47

对于细行,来自其他Q&A的程序不能工作,因为沿这条线的两条边太近了,程序无法将两者识别为单独的对象。

对于这样一条很细的线,你可以用更粗的线做一些不可能做到的事情:只要测量它的长度和面积,宽度就是这两条线的比例:

代码语言:javascript
复制
# `label_image` is as in the OP
# `id` is the label ID for the thin line
msr = dip.MeasurementTool.Measure(label_image.astype(np.uint32), features=['Size','Feret'])
area = msr[id]['Size'][0]
length = msr[id]['Feret'][0]

width = area / length

请注意,如果不立即对图像进行二值化,则应该能够获得更精确的值。链接Q&A使用灰度输入图像来确定边缘的位置,比二值化后更精确。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73807919

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档