测量圆形图像中掩模各部分的宽度

问题描述 投票:0回答:3

我有一个口罩:

按照这个方法

编码后得到的结果如下:

由于这是一个新的圆形而不是直线,因此使用上面的旋转方法测量宽度似乎不准确。有没有更好的方法来测量一个口罩各部分的宽度?

python opencv image-processing computer-vision
3个回答
2
投票

传统的线宽确定方法是通过距离变换。这是一种计算每个前景像素到背景的距离的算法。该距离沿线的中心最大,并且是线宽度的一半。

因为你的线是近似垂直的,所以我们可以只取每个图像行距离变换的最大值。这些值的平均值大约是平均宽度。

如果沿每行(或列)取最大值不会沿线的中心线产生良好的采样,则需要更复杂的算法来提取沿该中心线的值。

我这里使用DIPlib进行演示,其他库也会有距离变换。 [免责声明:我是 DIPlib 的作者。]

import diplib as dip
import numpy as np

img = dip.ImageRead('UVduo.png')
img = img > 128

dt = dip.EuclideanDistanceTransform(img)
width = dip.Maximum(dt, process=[True, False])
print(2 * np.mean(width))

这会输出

15.26
,即以像素为单位的平均宽度。


1
投票

如果你假设你的线的中轴代表你的线的宽度为一个像素,那么如果你的中轴由 N 个像素组成,但你的实际线由 3N 个像素组成,你可以说这是一个 “相当合理” 假设你的线是 3 像素宽。

#!/usr/bin/env python3

import cv2 as cv
import numpy as np
from skimage.morphology import medial_axis

# Load image and threshold
im = cv.imread("line.png", cv.IMREAD_GRAYSCALE)
_, thr = cv.threshold(im,127,255,cv.THRESH_BINARY)

# Count white pixels
nWhite = np.count_nonzero(thr)

# Get medial axis of white line and line length
skeleton = (medial_axis(thr*255)).astype(np.uint8)
nMedial = np.count_nonzero(skeleton)
cv.imwrite('DEBUG-skeleton.png',(skeleton*255).astype(np.uint8))

# Calculate average thickness
aveThickness = nWhite / nMedial
print(f'{aveThickness=}, {nWhite=}, {nMedial=}')

输出

aveThickness=18.186858316221766, nWhite=8857, nMedial=487


0
投票

根据您提供的其他答案,如果我没记错的话,您所需要的只是行间的宽度。为此,您只需在行上执行一个简单的

np.sum
操作,然后除以 255(假设它是一个仅包含 0 和 255 值的掩码)。这将为您提供每行的宽度。

# assuming mask is the image with shape WxHx1 having values 0 and 255
res = np.sum(mask, axis=1) / 255

在您提供的顶部图像上执行此操作,得到的平均宽度为 18.84,值范围在 12 到 25 之间。

© www.soinside.com 2019 - 2024. All rights reserved.