我有一张图片,我已经对这张图片做了一些预处理。下面我展示了我的预处理:
img= cv2.imread("...my_drive...\\image_69.tif",0)
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)
kernel=np.ones((1,13),np.uint8)
opening1= cv2.morphologyEx(closing2, cv2.MORPH_OPEN, kernel, iterations=2)
所以,基本上我使用了“阈值过滤”,“关闭”和“打开”,结果看起来像这样:
请注意,当我使用type(opening1)
时,我得到的是numpy.ndarray
。所以这一步的图像是numpy array
,大小为1021 x 1024。
然后我给我的图像贴上标签:
label_image=measure.label(opening1, connectivity=opening1.ndim)
props= measure.regionprops_table (label_image, properties=['label', "area", "coords"])
结果如下所示
请注意,当我使用type(label_image)
时,我得到了numpy.ndarray
。因此,这一步的图像是numpy array
,大小为1021 x 1024。
正如你所看到的,目前的图像有6个标签。这些标签中的一些是短和小块,所以我试图保持顶部2标签的基础上面积
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[:2]:
new_slc[tuple(rps[i].coords.T)]=i+1
现在,结果如下所示:
看起来我成功地保留了2个顶部区域(请注意,通过改变id[:2]
,您可以选择最厚的白色层或最薄的层)。现在:
**我想做的:**我想找出这两个区域的平均厚度
另外,请注意,我知道我的每个像素是314纳米
这里有谁能给我出个主意,我该怎么做这项工作?
原始照片:下面我显示了我的原始图像的低质量,所以你有更好的理解为什么我做了所有的预处理
您也可以在此处访问原始照片:https://www.mediafire.com/file/20h66aq83edy1h7/img.7z/file
3条答案
按热度按时间5fjcxozz1#
这里有一种在Python/OpenCV中实现这一点的方法。
输入:
阈值图像:
轮廓图像:
过滤后的轮廓图像:
backbone 图像:
x1c4d 1x指令集
Angular (以度为单位)和厚度(以像素为单位):
要获得以纳米为单位的厚度,请将以像素为单位的厚度乘以314纳米/像素。
增加
如果我从你的tiff图像开始,下面显示了我的预处理,它和你的类似。
阈值图像:
形态图像:
指令集
已筛选的线条图像:
backbone 图像:
指令集
Angular (度)和厚度(像素):
3wabscal2#
Deskew
拉直图像。c90pui9n3#
这可以通过scipy中的各种工具来完成。
如果放大,可以看到分割区域
为了避免这个问题我们可以扩张面罩
现在,我们可以找到连接区域,并找到具有最多像素的顶部区域,这应该是感兴趣的两条线:
以及
imshow(lab==max_labs[1])
x1c4d 1x以第一行为例:
在不同y轴截距处沿着此区域插值,并计算沿每条线的平均信号
指令集
使用您最喜欢的方法计算此轮廓的FWHM,然后乘以您的像素-纳米系数。
我会用高斯拟合来计算fwhm
最后,
thickness=fwhm*314
,或大约13微米。对第二条线(
lab==max_labs[1]
)采用完全相同的方法,得到约2.2微米的厚度:指令集
注意,我是使用交互式绘图来做这个例子的,因此调用
imshow
,plot
等只是为了给读者提供参考。你可能需要采取额外的步骤来重新创建我上传的图像(缩放等)。