简体   繁体   English

OpenCV 使用 cap.set(cv2.CAP_PROP_POS_FRAMES

[英]OpenCV getting very slow when using cap.set(cv2.CAP_PROP_POS_FRAMES

I'm using the following code to create a simple video player but I've seen that when I introduce the cap.set(cv2.CAP_PROP_POS_FRAMES,arg) line, the all process is getting very slow while playing the video.我正在使用以下代码创建一个简单的视频播放器,但我发现当我引入cap.set(cv2.CAP_PROP_POS_FRAMES,arg)行时,播放视频时整个过程变得非常缓慢。 The player works correctly with its trackbar but the speed is very slow.播放器可以正常使用其轨迹栏,但速度非常慢。 In general I noted that every time you use the cap.set(cv2.CAP_PROP_POS_FRAMES,...) command the speed get much slower than leaving the player going with ret, frame = cap.read() without setting the framenumber I need to use the cv2 because the purpose of job is to treat all frames by overlapping a text to every frame and show on the player (the text overlay code is not yet written here)一般来说,我注意到每次你使用cap.set(cv2.CAP_PROP_POS_FRAMES,...)命令时,速度都会比让玩家使用ret, frame = cap.read()而不设置我需要的帧数慢得多使用 cv2 因为作业的目的是通过将文本重叠到每一帧并在播放器上显示来处理所有帧(此处尚未编写文本覆盖代码)

import cv2
    
    
def on_trackbar(arg):
    global cap
    cap.set(cv2.CAP_PROP_POS_FRAMES,arg)

    filevideo = r'D:\Documenti\Regate\Progetti\VideoOverlayData\Sviluppo\VideoOverlayData\INPUTFILES\28AugRace5.MP4'
    cap = cv2.VideoCapture(filevideo)
    Videofps = cap.get(cv2.CAP_PROP_FPS)
    nr_of_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    
    if (cap.isOpened() == False):
            print("Error opening video stream or file")
            
    cv2.namedWindow('Frame', cv2.WINDOW_KEEPRATIO)
    cv2.createTrackbar("F", "Frame", 0, nr_of_frames, on_trackbar)
    videoCurrentFrameNumber = 0
    while(cap.isOpened()):
           # cap.set(1,videoCurrentFrameNumber)
            ret, frame = cap.read()
            if ret is True:
                cv2.imshow('Frame',frame)
                videoCurrentFrameNumber = int(cap.get(cv2.CAP_PROP_POS_FRAMES))
                #cap.set(cv2.CAP_PROP_POS_FRAMES,videoCurrentFrameNumber)
                #cap.set(5,50)
                cv2.setTrackbarPos('F','Frame',videoCurrentFrameNumber)
                #videoCurrentFrameNumber = videoCurrentFrameNumber +1
                frameclick = cv2.waitKey(1) & 0xFF
                if frameclick == ord('q'):
                       break
    cap.release()
    cv2.destroyAllWindows()

I had the same problem using python3 with opencv-python 4.5.5.64 on an m1 mac.我在 m1 mac 上使用python3opencv-python 4.5.5.64时遇到了同样的问题。 ( Last known version to work with trackbar , as of writing this article ) The best explanation i've found is that random access it is naturally slow. 最后一个使用 trackbar 的已知版本,截至撰写本文时)我发现的最佳解释是随机访问自然很慢。 Though, I recall using older versions of opencv-python with your code with absolutely no problem.不过,我记得在您的代码中使用旧版本的 opencv-python 绝对没有问题。 Needless to say, the solution that made most sense to my case was to load the entire video into memory and then display it.不用说,对我的情况最有意义的解决方案是将整个视频加载到 memory 中,然后显示它。 The code for my use-case is shown below, where I've build a video player with frame by frame ( a , b ) movement and play/pause ( spacebar ).我的用例代码如下所示,其中我构建了一个视频播放器,具有逐帧 ( a , b ) 移动和播放/暂停 ( spacebar )。 The default position is pause:默认 position 是暂停:

import cv2
import numpy as np
import datetime
import os
import sys

# import the video
videoFile = sys.argv[1];

# load capture
cap = cv2.VideoCapture(videoFile)
if (cap.isOpened()== False): 
  print("Error opening video stream or file")

# prepare view
view_name = "Video in memory"
total_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
cv2.namedWindow(view_name)
cv2.createTrackbar('S',view_name, 0,int(total_frames)-1, lambda x:x)
cv2.setTrackbarPos('S',view_name,0)

# read the entire video to memory
print("[INFO] loading frames to memory")
all_frames = []
while(cap.isOpened()):
    frame_exists, frame = cap.read()
    if frame_exists == True:
        all_frames.append(frame)
    else:
        break

# When everything done, release the video capture object
cap.release()
print("[INFO] load compelte");

# set default play state to pause
status = 'pause'
previous_status = 'pause'
frame_idx = 0
while True:
    try:
        if frame_idx==total_frames-1:
            frame_idx=0

        frame = all_frames[frame_idx]
        cv2.imshow(view_name,frame)

        # event handling
        keyPress = cv2.waitKey(1)
        if keyPress & 0xFF == ord(' '):
            status = 'play_pause_click'
        elif keyPress & 0xFF == ord('a'):
            status = 'prev_frame'
        elif keyPress & 0xFF == ord('d'):
            status = 'next_frame'
        elif keyPress & 0xFF == -1:
            status = status
        elif keyPress & 0xFF == ord('q'):
            status = 'exit'

        if (status == 'play_pause_click' and previous_status == 'play_pause_click'):
            status = 'pause'
            previous_status = 'pause'
        if (status == 'play_pause_click'):
            status = 'play'
            previous_status = 'play_pause_click'

        if status == 'play':
            frame_idx += 1
            cv2.setTrackbarPos('S',view_name,frame_idx)
            continue
        if status == 'pause':
            frame_idx = cv2.getTrackbarPos('S',view_name)
        if status=='prev_frame':
            frame_idx-=1
            frame_idx = max(0, frame_idx)
            cv2.setTrackbarPos('S',view_name,frame_idx)
            status='pause'
        if status=='next_frame':
            frame_idx+=1
            cv2.setTrackbarPos('S',view_name,frame_idx)
            status='pause'
        if status == 'exit':
            break

    except KeyError:
        print("Invalid Key was pressed")
 
# Closes the generated window
cv2.destroyWindow(view_name)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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