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.
np.argmax
to find maximum for each row I would also recommend
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.