在图像中提取激光线(使用OpenCV)

bt1cpqcv  于 2023-10-24  发布在  其他
关注(0)|答案(2)|浏览(156)

我有一张来自激光线的照片,我想从图像中提取出那条线。

由于激光线是红色的,我取图像的红色通道,然后在每行中搜索最高强度:

现在的问题是,也有一些点不属于激光线(如果你放大到第二张图片,你可以看到这些点)。
有没有人对接下来的步骤有什么想法(删除单点并提取线)?
这是另一种检测线条的方法:首先,我用内核模糊了“黑白”线条,然后将模糊的线条细化( backbone )为细线,然后应用OpenCV函数检测线条。结果如下图所示:

  • 新:*

现在我有另一个更难的情况。我必须提取一个绿色激光。
这里的问题是,激光线的颜色范围更宽,并且不断变化。
在激光线的某些部分上,像素仅具有高的绿色分量,而在其他部分上,像素也具有高的蓝色分量。

4dc9hkyq

4dc9hkyq1#

获取每一行中的最高值将始终输出一个值,而不是忽略值不够高的情况。考虑使用阈值,以便您可以丢弃不够高的值。
然而,这并不是一个非常有效的方法。一个更好更简单的解决方案是使用OpenCV函数inRange();定义所有三个通道中红色的下限和上限,这将返回一个二进制图像,其中图像强度在BGR范围内,具有白色像素。
这是在python中,但它做的工作,应该很容易看到如何使用函数:

  1. import cv2
  2. import numpy as np
  3. img = cv2.imread('image.png')
  4. lowerb = np.array([0, 0, 120])
  5. upperb = np.array([100, 100, 255])
  6. red_line = cv2.inRange(img, lowerb, upperb)
  7. cv2.imshow('red', red_line)
  8. cv2.waitKey(0)

这将产生输出:x1c 0d1x
这可以通过寻找轮廓或其他方法来进一步处理,以将这些点变成一条漂亮的曲线。

展开查看全部
ccrfmcuu

ccrfmcuu2#

我真的很抱歉没有任何代码的简短回答,但我建议你采取轮廓和处理它们。
我不知道你需要什么,所以这里有两个方法:

  • 只是收集尽可能多的轮廓在一条线(使用中心,并尝试找到直线与最小的平均值)
  • 作为第一种方法,但尝试将分离的线条结合起来....这要困难得多,但这可能会给予你几乎完整的激光线从图像。

--
举个例子,你的图片:

  1. import cv2
  2. import numpy as np
  3. import math
  4. img = cv2.imread('image.png')
  5. hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
  6. # filtering red area of hue
  7. redHueArea = 15
  8. redRange = ((hsv[:, :, 0] + 360 + redHueArea) % 360)
  9. hsv[np.where((2 * redHueArea) > redRange)] = [0, 0, 0]
  10. # filtering by saturation
  11. hsv[np.where(hsv[:, :, 1] < 95)] = [0, 0, 0]
  12. # convert to rgb
  13. rgb = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
  14. # select only red grayscaled channel with low threshold
  15. gray = cv2.cvtColor(rgb, cv2.COLOR_RGB2GRAY)
  16. gray = cv2.threshold(gray, 15, 255, cv2.THRESH_BINARY)[1]
  17. # contours processing
  18. (_, contours, _) = cv2.findContours(gray.copy(), cv2.RETR_LIST, 1)
  19. for c in contours:
  20. area = cv2.contourArea(c)
  21. if area < 8: continue
  22. epsilon = 0.1 * cv2.arcLength(c, True) # tricky smoothing to a single line
  23. approx = cv2.approxPolyDP(c, epsilon, True)
  24. cv2.drawContours(img, [approx], -1, [255, 255, 255], -1)
  25. cv2.imshow('result', img)
  26. cv2.waitKey(0)

在你的情况下,它的工作完美,但是,正如我已经说过的,你将需要做更多的工作与轮廓。

展开查看全部

相关问题