【问题标题】:Playback loop option in OpenCV videosOpenCV 视频中的播放循环选项
【发布时间】:2013-06-14 01:27:58
【问题描述】:

我正在尝试为 OpenCV 视频构建一个播放循环选项。我的程序使用 Python 多处理,并有一个按钮通过 queue4 发送 loopswitch 调用以启用或禁用循环选项。我的具体问题是我的视频在最后一帧冻结,我想知道vidFile.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, 1) 行是否正确使用cv2.VideoCapture.set() 方法,并且确实应该将视频取回帧 1 并重播(我认为应该如此)。

编辑

修改我的代码后,它现在触发运行时 C++ 错误,但没有给出其他精度。 根据this answer 的说法,使用cv2.VideoCapture.set() 在帧之间跳转似乎是错误的。有人管理过吗?

谢谢,

我的捕获过程代码(queue和queue2在队列中):

def image_capture(queue, con, queue2, queue4):
    videopath = con.recv()
    vidFile = cv2.VideoCapture(videopath)
    fps = vidFile.get(cv2.cv.CV_CAP_PROP_FPS)
    waitframe = 1/fps
    con.send(waitframe)#sending waitkey duration through pipe to update_image()
    loopswitch = False #init for playing video in a loop 
    while True:
        if queue4.empty():
           pass
        else:
           queueval = queue4.get()
            if queueval=='loop':
               if loopswitch==False:
                  loopswitch = True
               elif loopswitch==True:
                  loopswitch = False
        try:
            flag, frame=vidFile.read()
            if flag==0:
               if loopswitch==False:
                  queue2.put(None)
                  break
               elif loopswitch==True:
                  vidFile.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, 1)
                  continue
            else:                
               queue2.put(frame)
               cv2.waitKey(waitframe)
        except:
            continue

【问题讨论】:

    标签: python opencv video-capture


    【解决方案1】:
    self.cap =cv2.VideoCapture(self.filename)       
    while True:
    
        ret,frameset = self.cap.read()
                 
        if self.cap.get(1)>self.cap.get(7)-2:#video loop
            self.cap.set(1,0)#if frame count > than total frame number, next frame will be zero
        cv2.imshow("G",frameset)
        key = cv2.waitKey(1)
        if key == 27:
            break
    self.cap.release()
    cv2.destroyAllWindows()
    

    【讨论】:

    • 当帧数与总帧数匹配时,总是会重新开始捕获 - 2(我使用 -2 来保持 while True)
    【解决方案2】:

    当帧计数达到cap.get(cv2.CAP_PROP_FRAME_COUNT) 然后将帧计数和cap.set(cv2.CAP_PROP_POS_FRAMES, num) 重置为相同值时,我可以使用 if 语句来循环播放视频。下面的示例一直为我循环播放视频。

    import cv2
    
    cap = cv2.VideoCapture('path/to/video') 
    frame_counter = 0
    while(True):
        # Capture frame-by-frame
        ret, frame = cap.read()
        frame_counter += 1
        #If the last frame is reached, reset the capture and the frame_counter
        if frame_counter == cap.get(cv2.CAP_PROP_FRAME_COUNT):
            frame_counter = 0 #Or whatever as long as it is the same as next line
            cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
        # Our operations on the frame come here
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # Display the resulting frame
        cv2.imshow('frame',gray)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    # When everything done, release the capture
    cap.release()
    cv2.destroyAllWindows()
    

    它还可以重新捕获视频,而不是重置帧数:

    if frame_counter == cap.get(cv2.CAP_PROP_FRAME_COUNT):
        frame_counter = 0
        cap = cv2.VideoCapture(video_name)
    

    所以至少我可以使用cap.set(cv2.CAP_PROP_POS_FRAMES, num) 循环播放视频。如果您重置到第零帧而不是第一帧(如使用 avi 方法)会发生什么?

    【讨论】:

    • 来自另一个用户的评论,代表不足,无法在此处输入:我正在使用 cv2 (v.3.0.0),发现 frame_counter 从来没有 == 到 cap.get(cv2 .CAP_PROP_FRAME_COUNT):因为 cv2.CAP_PROP_FRAME_COUNT 是双精度数,但计数器不是。我还没来得及测试他的建议。
    【解决方案3】:

    对于 C++ 人:

    void openVideo() {
        cap.open(videoName);
        if (!cap.isOpened()) {
            std::cout << "Video file not loaded!" << std::endl;
        }
    
        numberOfFrames = (int)cap.get(cv::CAP_PROP_FRAME_COUNT);
    
        //--- GRAB AND WRITE LOOP
        std::cout << "Start grabbing" << std::endl
            << "Press any key to terminate" << std::endl;
        for (;;)
        {
            // wait for a new frame from camera and store it into 'frame'
            cap.read(frame);
            frameCounter++;
            // check if we succeeded
            if (frameCounter == numberOfFrames) {
                frameCounter = 0;
                cap.set(cv::CAP_PROP_POS_FRAMES, 0);
            }
            if (frame.empty()) {
                std::cerr << "ERROR! blank frame grabbed\n";
                break;
            }
            // show live and wait for a key with timeout long enough to show images
            cv::imshow("Live", frame);
            if (cv::waitKey(5) >= 0)
                break;
        }
        // the camera will be deinitialized automatically in VideoCapture destructor
    }
    

    【讨论】:

      【解决方案4】:

      对于python3、opencv3.1.0、树莓派3

      import numpy as np
      import cv2
      cap = cv2.VideoCapture('intro.mp4')
      while(cap.isOpened()):
      
          ret, frame = cap.read() 
          #cv2.namedWindow("window", cv2.WND_PROP_FULLSCREEN)
          #cv2.setWindowProperty("window",cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
      
          if ret:
              cv2.imshow("Image", frame)
          else:
             print('no video')
             cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
      
          if cv2.waitKey(1) & 0xFF == ord('q'):
              break
      
      
      cap.release()
      cv2.destroyAllWindows()
      

      【讨论】:

        【解决方案5】:

        我通过将 vidFile.set (cv2.cv.CV_CAP_PROP_POS_FRAMES, 1) 替换为 vidFile.set(cv2.cv.CV_CAP_PROP_POS_AVI_RATIO, 0) 部分解决了这个问题,尽管这仅适用于 .avi 文件。

        【讨论】:

          猜你喜欢
          • 2020-10-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多