I am writing a program that draws a line on a video where the first pixels of the railing are encountered, my problem is that the video playback is sluggish.
Screenshot for reference of what the video looks like. During the video the camera is moved closer but because of the slow speed, I have to wait a few minutes to see the change, but when filming took place, it was moved every few seconds.
I assume the issue is the fact that the for loops are operating on every single frame of the video but I am not sure.
What solution could I implement to speed up my program?
import cv2
cap = cv2.VideoCapture('video.mp4')
while(cap.isOpened()):
ret, frame = cap.read()
canny = cv2.Canny(frame, 85, 255)
height, width = canny.shape
first_black_array = []
for x in range(width):
first_black_pixel_found = 0
for y in range(height):
if first_black_pixel_found == 0:
if canny[y,x] == 255:
first_black_array.append(height - y)
first_black_pixel_found = 1
cv2.line(frame,(x,y),(x,y),(0,255,0),1)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Thanks!
This is the problem...
for x in range(width):
for y in range(height):
if canny[y,x] == 255:
Numpy.argmax is the solution...
for x in range(width-1):
# Slice the relevant column from the image
# The image 'column' is a tall skinny image, only 1px thick
column = np.array(canny[:,x:x+1])
# Use numpy to find the first non-zero value
railPoint = np.argmax(column)
Full Code:
import cv2, numpy as np, time
# Get start time
start = time.time()
# Read in the image
img = cv2.imread('/home/stephen/Desktop/rail.jpg')[40:,10:-10]
# Canny filter
canny = cv2.Canny(img, 85, 255)
# Get height and width
height, width = canny.shape
# Create list to store rail points
railPoints = []
# Iterate though each column in the image
for position in range(width-1):
# Slice the relevant column from the image
# The image 'column' is a tall skinny image, only 1px thick
column = np.array(canny[:,position:position+1])
# Use numpy to find the first non-zero value
railPoint = np.argmax(column)
# Add the railPoint to the list of rail points
railPoints.append(railPoint)
# Draw a circle on the image
cv2.circle(img, (position, railPoint), 1, (123,234,123), 2)
cv2.imshow('img', img)
k = cv2.waitKey(1)
cv2.destroyAllWindows()
print(time.time() - start)
My solution using Numpy took 6ms and your solution took 266ms.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With