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

c++ - 提取图像中的激光线(使用OpenCV)-LMLPHP

由于激光线是红色的,因此我选择了图像的红色 channel ,然后在每一行中搜索最高的强度:

c++ - 提取图像中的激光线(使用OpenCV)-LMLPHP

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

有谁知道下一步的想法(删除单个点并提取线)?

那是检测线的另一种方法:
首先,我将带有内核的“黑白”线模糊掉,然后将模糊的线细化(骨架)为细线,然后应用OpenCV函数检测该线。结果如下图所示:c++ - 提取图像中的激光线(使用OpenCV)-LMLPHP

新功能:

现在,我有另一个更困难的情况。
我必须提取绿色激光。
这里的问题是激光线的颜色范围更宽且不断变化。
在激光线的某些部分上,像素仅具有较高的绿色成分,而在其他部分上,像素也具有较高的蓝色成分。
c++ - 提取图像中的激光线(使用OpenCV)-LMLPHP

最佳答案

对于没有任何代码的简短回答,我感到非常抱歉,但是我建议您选择轮廓并进行加工。

我不知道您到底需要什么,因此这里有两种方法供您选择:

  • 只是在单条线上收集尽可能多的轮廓(使用中心并尝试找到均值最小的直线)
  • 是第一种方法,但是尝试通过试探法将分离的线组合起来....要困难得多,但是这可能会给您几乎来自图像的完整激光线。

  • --

    您的图片的一些示例:
    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)
    

    在您的情况下,它可以完美地工作,但是,正如我已经说过的那样,您将需要对轮廓进行更多的工作。

    关于c++ - 提取图像中的激光线(使用OpenCV),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44389702/

    10-10 17:27