首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在图像中提取激光线(使用OpenCV)

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

Stack Overflow用户
提问于 2017-06-06 12:12:34
回答 2查看 5.8K关注 0票数 7

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

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

现在的问题是,也有一些点不属于激光线(如果你放大到第二张图片,你可以看到这些点)。

有没有人对接下来的步骤有一个想法(删除单个点,同时提取线条)?

这是另一种检测直线的方法:首先,我用内核模糊掉了那条“黑白”线,然后我细化了(骨架)那条模糊的线,然后我应用了一个OpenCV函数来检测这条线。结果如下图所示:

NEW:

现在我又遇到了更困难的情况。我得提取一个绿色的激光。

这里的问题是激光线的颜色范围更宽,而且变化很大。

在激光线的某些部分,像素只有高绿色分量,而在其他部分,像素也有高蓝色分量。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-06 12:27:11

我真的很抱歉,简短的答案没有任何代码,但我建议你采取轮廓,并处理他们。

我不知道你到底需要什么,所以这里有两种方法:

  • 尽可能多地在单线上收集等高线(使用中心,尝试用最小的平均值找到直线)。
  • 作为第一条路,但试着把分隔线结合起来.这要难得多,但这可能会给你提供几乎完整的激光线从图像。

--

你的照片的一些例子:

代码语言:javascript
复制
import cv2
import numpy as np
import math

img = cv2.imread('image.png')
hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
# filtering red area of hue
redHueArea = 15
redRange = ((hsv[:, :, 0] + 360 + redHueArea) % 360) 
hsv[np.where((2 * redHueArea) > redRange)] = [0, 0, 0] 
# filtering by saturation
hsv[np.where(hsv[:, :, 1] < 95)] = [0, 0, 0]
# convert to rgb
rgb = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
# select only red grayscaled channel with low threshold  
gray = cv2.cvtColor(rgb, cv2.COLOR_RGB2GRAY)
gray = cv2.threshold(gray, 15, 255, cv2.THRESH_BINARY)[1]
# contours processing
(_, contours, _) = cv2.findContours(gray.copy(), cv2.RETR_LIST, 1)
for c in contours:
    area = cv2.contourArea(c)
    if area < 8: continue
    epsilon = 0.1 * cv2.arcLength(c, True) # tricky smoothing to a single line
    approx = cv2.approxPolyDP(c, epsilon, True)
    cv2.drawContours(img, [approx], -1, [255, 255, 255], -1)

cv2.imshow('result', img)
cv2.waitKey(0)

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

票数 1
EN

Stack Overflow用户

发布于 2017-06-06 12:33:33

获取每一行中的最高值将始终输出一个值,而不是忽略值不够高的情况。也可以考虑使用阈值,这样就可以丢弃那些不够高的阈值。

然而,这并不是一个非常有效的方法来做到这一点。一个更好更容易的解决方案是使用OpenCV函数inRange();在所有三个通道中为红色定义一个下界和上界,这将返回图像强度在该BGR范围内的白色像素的二值图像。

这是python中的,但是它可以完成这项工作,应该很容易看到如何使用这个函数:

代码语言:javascript
复制
import cv2
import numpy as np

img = cv2.imread('image.png')
lowerb = np.array([0, 0, 120])
upperb = np.array([100, 100, 255])
red_line = cv2.inRange(img, lowerb, upperb)

cv2.imshow('red', red_line)
cv2.waitKey(0)

这将产生输出:

这可以通过找到等高线或其他方法来进一步处理,从而将点转化为一条很好的曲线。

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

https://stackoverflow.com/questions/44389702

复制
相关文章

相似问题

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