我有一条激光线的照片,我想从图像中提取那条线。
由于激光线是红色的,因此我选择了图像的红色 channel ,然后在每一行中搜索最高的强度:
现在的问题是,还有一些不属于激光线的点(如果放大第二张图片,您会看到这些点)。
有谁知道下一步的想法(删除单个点并提取线)?
那是检测线的另一种方法:
首先,我将带有内核的“黑白”线模糊掉,然后将模糊的线细化(骨架)为细线,然后应用OpenCV函数检测该线。结果如下图所示:
新功能:
现在,我有另一个更困难的情况。
我必须提取绿色激光。
这里的问题是激光线的颜色范围更宽且不断变化。
在激光线的某些部分上,像素仅具有较高的绿色成分,而在其他部分上,像素也具有较高的蓝色成分。
最佳答案
对于没有任何代码的简短回答,我感到非常抱歉,但是我建议您选择轮廓并进行加工。
我不知道您到底需要什么,因此这里有两种方法供您选择:
--
您的图片的一些示例:
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/