如何从 2 个图像中检测激光线并使用 python opencv 计算其中心?

How do I detect laser line from 2 images and calculate its center using python opencv?

如何使用两张图像检测激光线,第一张激光关闭,第二张激光打开,然后计算其中心? 这些是我的图片: img1.jpg img2.jpg

这是我的代码:

import cv2
import time

img1 = cv2.imread("img1.jpg")
img2 = cv2.imread("img2.jpg")
img_org = img1
img1 = img1[:,:,2]
img2 = img2[:,:,2]

diff = cv2.absdiff(img1, img2)
diff = cv2.medianBlur(diff,5)
ret, diff = cv2.threshold(diff ,0 ,255 ,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

cv2.imwrite("output1.png", diff)

count = 0

height, width = diff.shape[:2]

start = time.time() # time start

for y in range(height):
    for x in range(width):
        if diff[y,x] == 255:
            count += 1
        elif not count == 0:
            img_org[y, round(x - count/2)] = [0, 255, 0]
            count = 0

end = time.time() # time stop
print(end - start)

cv2.imwrite("output2.png", img_org)

cv2.waitKey(0)

此代码从两个图像中提取红色通道,比较它们以检测差异,然后对差异图像进行模糊和阈值处理。这不够好,因为顶部有一些不应该存在的白色。 output1.png (diff)

为了检测阈值线的中心,我尝试遍历阈值图像的每一行和像素,计算白色像素。它可以正常工作,但由于 python 循环和数组速度慢,计算一张 4032x2268 阈值图像需要大约 16 秒。为了测试我的代码,将激光线中心设置为 output2.png 上的绿色像素。 output2.png (img_org)

如何使激光检测更准确并使线中心计算更快? 我是 opencv 的新手。

  1. 差异
  2. 高斯模糊以抑制噪声,并对饱和部分进行平滑处理
  3. np.argmax 求每行的最大值

我也会推荐

  • 进一步减少曝光
  • PNG 而不是 JPEG 用于实际处理。 JPEG 保存 space,适合在网络上查看。

伽玛曲线在这里并不重要。只要确保环境比激光暗即可。精确的计算取决于它到底是什么颜色 space,2.2 指数是 the actual curve

的一个很好的近似值
im0 = cv.imread("background.jpeg")
im1 = cv.imread("foreground.jpeg")
(height, width) = im0.shape[:2]

# gamma stuff, make values linear
#im0 = (im0 / np.float32(255)) ** 2.2
#im1 = (im1 / np.float32(255)) ** 2.2

diff = cv.absdiff(im1, im0)
diff = cv.GaussianBlur(diff, ksize=None, sigmaX=3.0)
plane = diff[:,:,2] # red
indices = np.argmax(plane, axis=1) # horizontally, for each row

out = diff.copy() # "drawing" 3 pixels thick
out[np.arange(height), indices-1] = (0,255,0)
out[np.arange(height), indices  ] = (0,255,0)
out[np.arange(height), indices+1] = (0,255,0)
cv.imwrite("out.jpeg", out)