简体   繁体   中英

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

How can I detect laser line using 2 images, first with laser turned off and second with turned on and then calculate its center? These are my images: img1.jpg img2.jpg

This is my code:

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)

This code takes red channel from both images, compare them to detect difference, then blur and treshold the difference image. This doesnt work good enought because on the top is some white that shouldn't be there. output1.png (diff)

For detecting center of thresholded line I have tried looping through every row and pixel of the threshold image, counting white pixels. It works correcly but because of slow python loops and arrays calculating one 4032x2268 thresholded image takes about 16 seconds. For testing my code is setting laser line center to green pixels on output2.png. output2.png (img_org)

How can I make laser detection more accurate and center of line calculation way faster? I'm fairly new to opencv.

  1. difference
  2. gaussian blur to suppress noise, and smooth over saturated sections
  3. np.argmax to find maximum for each row

I would also recommend

  • some more reduction in exposure
  • PNG instead of JPEG for real processing. JPEG saves space, okay for viewing on the web.

Gamma curves don't necessarily matter here. Just make sure the environment is darker than the laser. Exact calculation depends on what color space it is exactly, and the 2.2 exponent is a good approximation of 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)

出去

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM