In preparing to process a video I want the user to be able to select the first and last frame to be processed in the video. The trackbar seems like a useful tool to do this but can I use it to read and display specific frames from a video?
Typically I read a video in frame-by-frame and run my processing algorithm on it, using a while loop:
cap = cv2.VideoCapture('myvideo.mp4')
while(cap.isOpened()):
ret, frame = cap.read()
# ....
This is not conducive to having the user quickly scan through the video to find a good frame interval to process.
The trackbar is great for setting image processing parameters, but if there is a better tool that you can think of for this please suggest. Below you can see some code for setting a threshold level variable using a trackbar.
def onTrackbarChange(trackbarValue):
pass
cv2.createTrackbar( 'threshold level', 'mywindow', 100, 255, onTrackbarChange )
thresholdlevel = cv2.getTrackbarPos('thresh','mywindow')
Is there a way to do something like this?
start_frame = cv2.getTrackbarPos('start-frame','mywindow')
ret, frame = cap.read(start_frame) #don't think this is possible
cv2.imshow('window', frame)
Ideally there would be two window panels, one with the start_frame, and one with the stop_frame, each controlled by a trackbar.
解决方案
first of all, you can set the video position with:
cap.set(cv2.CAP_PROP_POS_FRAMES,pos)
then it's just putting together the pieces, let them play with the trackbars, when a key was pressed, play the interval:
import cv2
cap = cv2.VideoCapture('david.mpg')
length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
def onChange(trackbarValue):
cap.set(cv2.CAP_PROP_POS_FRAMES,trackbarValue)
err,img = cap.read()
cv2.imshow("mywindow", img)
pass
cv2.namedWindow('mywindow')
cv2.createTrackbar( 'start', 'mywindow', 0, length, onChange )
cv2.createTrackbar( 'end' , 'mywindow', 100, length, onChange )
onChange(0)
cv2.waitKey()
start = cv2.getTrackbarPos('start','mywindow')
end = cv2.getTrackbarPos('end','mywindow')
if start >= end:
raise Exception("start must be less than end")
cap.set(cv2.CAP_PROP_POS_FRAMES,start)
while cap.isOpened():
err,img = cap.read()
if cap.get(cv2.CAP_PROP_POS_FRAMES) >= end:
break
cv2.imshow("mywindow", img)
k = cv2.waitKey(10) & 0xff
if k==27:
break