使用 OpenCV 测量热钢板的宽度

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

我想测量图像中绿线的宽度,我通过 OpenCV 应用了像 canny 这样的滤镜,但我猜由于温度非常高,滤镜不起作用(无法显示边缘)。我的想法是画两条垂直线,并通过在它们之间画一条线来测量(我想画出图片中物体的垂直边缘,所以)。有什么方法可以解决这个问题吗?

python opencv image-processing computer-vision edge-detection
3个回答
1
投票

红色分量的二值化效果非常好,所以找到边并不是什么大问题。

为了获得更高的精度,您可以垂直进行低通滤波以减少噪声。您还可以使用跨边缘的线性模型进行子像素插值。但我不确定您的情况是否需要这种奢侈。

低通:


1
投票
  • 取一行像素
  • 只走红色通道(其他不包含任何信息)
  • 稍微低通它以抑制噪音
  • 渐变
  • 最大和最小是上升沿和下降沿

由此,

falling - rising
,您可以直接获得工件在穿过图像的扫描线上的宽度(以像素为单位)。

您也可以,也许应该,使用全局阈值而不是寻找边缘。在此图中,阈值 0.4 看起来不错。你可以用大津的方法来确定。

im = cv.imread("UEj1P.png")

# try threshold using Otsu
row_u8 = im[550, :, 2] # red channel
(otsulevel, thresh) = cv.threshold(row_u8, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)

row = im[500:550, :, 2].mean(axis=0) / 255

lowpassed = scipy.ndimage.gaussian_filter1d(row, sigma=2.0)

gradient = np.gradient(lowpassed)

rising = np.argmax(gradient)
falling = np.argmin(gradient)

# two plots in the figure
fig, ax = plt.subplots(2, 1, figsize=(15, 10))

# first plot: row
ax[0].plot(row)
ax[0].plot(lowpassed)

# otsu threshold line
ax[0].axhline(otsulevel/255, color="blue")

# second plot: gradient
ax[1].plot(gradient)

# draw some vertical lines at rising and falling edge
ax[0].axvline(x=rising, color="red")
ax[0].axvline(x=falling, color="red")
ax[1].axvline(x=rising, color="red")
ax[1].axvline(x=falling, color="red")

plt.show()


0
投票

我也有同样的问题。就像这张图,如果曲线中有噪音怎么办?如何消除这种噪音?

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