如何从 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 的新手。
- 差异
- 高斯模糊以抑制噪声,并对饱和部分进行平滑处理
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)
如何使用两张图像检测激光线,第一张激光关闭,第二张激光打开,然后计算其中心? 这些是我的图片: 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 的新手。
- 差异
- 高斯模糊以抑制噪声,并对饱和部分进行平滑处理
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)