添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

OpenCV视频中的循环播放选项

10 人关注

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

在修改了我的代码后,现在触发了一个运行时的C++错误,但没有给出其他的预判。 根据 这个答案 替换代码3】在帧间跳转似乎是个错误。有谁能做到这一点?

我的捕获过程的代码( 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():
        else:
           queueval = queue4.get()
            if queueval=='loop':
               if loopswitch==False:
                  loopswitch = True
               elif loopswitch==True:
                  loopswitch = False
            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
Raoul
Raoul
发布于 2013-06-18
5 个回答
Tony
Tony
发布于 2020-04-15
已采纳
0 人赞同

用于Python3, opencv3.1.0, raspberry pi 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)
       continue
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()
    
对我来说,在cap.set()之后添加 continue 是有意义的,这样循环就会重新开始,而我在框架上工作的其他代码还不会运行。只是给那些尝试这样做而没有立即得到它的人提个醒。
Raoul
Raoul
发布于 2020-04-15
0 人赞同

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

joelostblom
joelostblom
发布于 2020-04-15
0 人赞同

我可以通过对帧数达到 cap.get(cv2.CAP_PROP_FRAME_COUNT) 时使用if语句,然后将帧数和 cap.set(cv2.CAP_PROP_POS_FRAMES, num) 重置为相同的值,从而获得循环视频播放。下面的例子为我保持了视频的循环播放。

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是一个双数,但计数器却不是。 .我还没有时间来测试他的建议。
Omi
frame_counter == cap.get(cv2.CAP_PROP_FRAME_COUNT)这一行需要把 frame_counter == cap.get(cv2.CAP_PROP_FRAME_COUNT)-1。
Gilberto Marchiori
Gilberto Marchiori
发布于 2020-04-15
0 人赞同
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)。
Felipe Gutierrez
Felipe Gutierrez
发布于 2020-04-15
0 人赞同

For the C++ guys:

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)