"""
read() and grab() in OpenCV VideoCapture takes different time as there is no
decoding for grab() operation. Let's try to find out how much these two methods
differs.
"""import cv2
defmain():
tm = cv2.TickMeter()# =========================================================================# Test 1, grab and decode each frame.
cap = cv2.VideoCapture()
cap.open("/home/robin/Videos/clip1-ssd.mp4", cv2.CAP_FFMPEG)
total_frame_count = cap.get(cv2.CAP_PROP_FRAME_COUNT)
tm.start()# print("Total frames number: {}".format(total_frame_count))
f_count =0whileTrue:
f_count +=1
r, img = cap.read()if r ==False:break# for _ in range(24):# cap.grab()
tm.stop()print("Read and decode {} frames takes {} seconds.".format(
f_count, tm.getTimeSec()/tm.getCounter()))# =========================================================================# Test 2, grab only without decoding.
cap = cv2.VideoCapture()
cap.open("/home/robin/Videos/clip1-ssd.mp4", cv2.CAP_FFMPEG)
total_frame_count = cap.get(cv2.CAP_PROP_FRAME_COUNT)
tm.reset()
tm.start()whileTrue:
r = cap.grab()if r ==False:break
tm.stop()print("Read {} frames takes {} seconds.".format(
total_frame_count, tm.getTimeSec()/tm.getCounter()))# =========================================================================# Test 3, reading same file with two decoders. This block failed on my PC.# Maybe it's not supported by FFMPEG?from multiprocessing.pool import ThreadPool
thread_num = cv2.getNumberOfCPUs()
pool = ThreadPool(processes=thread_num)defget_frame_at(src, location):
cap = cv2.VideoCapture()
cap.open(src, cv2.CAP_FFMPEG)
cap.set(cv2.CAP_PROP_FRAME_COUNT, location)
rst, frame = cap.read()return rst, frame
defget_frame_next(cap):
rst, frame = cap.read()return rst, frame
video_src ="/home/robin/Videos/clip1-ssd.mp4"
cap1 = cv2.VideoCapture()
cap1.open(video_src, cv2.CAP_FFMPEG)
cap2 = cv2.VideoCapture()
cap2.open(video_src, cv2.CAP_FFMPEG)
tm.reset()
tm.start()
f_count =0whileTrue:
f_count +=1
t1 = pool.apply_async(get_frame_next,(cap1,))
t2 = pool.apply_async(get_frame_next,(cap2,))print(t1.get()[0])if(t1.get()[0]isFalse)and(t2.get()[0]isFalse):break
tm.stop()print("Decode same file with 2 decoder takes {} seconds.".format(
tm.getTimeSec()/tm.getCounter()))if __name__ =="__main__":
main()
然后清楚了grab的含义,我们就可以对开始的
fp +=1
success = cap.grab()if(fp %2==0):continue
_,image = cap.retrive()