OpenCV视频中的播放循环选项

时间:2013-06-17 23:46:18

标签: python opencv video-capture

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

修改

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

谢谢,

我的捕获过程代码(queuequeue2是进出队列):

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

5 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

我可以通过在帧计数达到cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT)时使用if语句然后将帧计数和cap.set(cv2.cv.CV_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.cv.CV_CAP_PROP_FRAME_COUNT):
        frame_counter = 0 #Or whatever as long as it is the same as next line
        cap.set(cv2.cv.CV_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.cv.CV_CAP_PROP_FRAME_COUNT):
    frame_counter = 0
    cap = cv2.VideoCapture(video_name)

所以至少我可以使用cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, num)来循环播放视频。如果重置为第0帧而不是第1帧(如使用avi方法)会发生什么?

答案 2 :(得分:1)

对于python3,opencv3.1.0,raspberry pi 3

[
    {
        "Strength": 12,
        "Intelligence": 0,
        "Defense": 0,
        "Resistance": 0,
        "Accuracy": 0,
        "Agility": 0,
        "Speed": 0,
        "CurrentAP": 0,
        "CurrentHP": 0,
        "Affinity": 0,
        "Poison": 0,
        "Weakness": 0,
        "Paralysis": 0,
        "LifeStatus": 0
    },
    {
        "Strength": 0,
        "Intelligence": 0,
        "Defense": 0,
        "Resistance": 0,
        "Accuracy": 0,
        "Agility": 0,
        "Speed": 0,
        "CurrentAP": 0,
        "CurrentHP": 0,
        "Affinity": 0,
        "Poison": 0,
        "Weakness": 0,
        "Paralysis": 0,
        "LifeStatus": 0
    },
    {
        "Strength": 0,
        "Intelligence": 0,
        "Defense": 0,
        "Resistance": 0,
        "Accuracy": 0,
        "Agility": 0,
        "Speed": 0,
        "CurrentAP": 0,
        "CurrentHP": 0,
        "Affinity": 0,
        "Poison": 0,
        "Weakness": 0,
        "Paralysis": 0,
        "LifeStatus": 0
    },
    {
        "Strength": 0,
        "Intelligence": 0,
        "Defense": 0,
        "Resistance": 0,
        "Accuracy": 0,
        "Agility": 0,
        "Speed": 0,
        "CurrentAP": 0,
        "CurrentHP": 0,
        "Affinity": 0,
        "Poison": 0,
        "Weakness": 0,
        "Paralysis": 0,
        "LifeStatus": 0
    },
    {
        "Strength": 0,
        "Intelligence": 0,
        "Defense": 0,
        "Resistance": 0,
        "Accuracy": 0,
        "Agility": 0,
        "Speed": 0,
        "CurrentAP": 0,
        "CurrentHP": 0,
        "Affinity": 0,
        "Poison": 0,
        "Weakness": 0,
        "Paralysis": 0,
        "LifeStatus": 0
    },
    {
        "Strength": 0,
        "Intelligence": 0,
        "Defense": 0,
        "Resistance": 0,
        "Accuracy": 0,
        "Agility": 0,
        "Speed": 0,
        "CurrentAP": 0,
        "CurrentHP": 0,
        "Affinity": 0,
        "Poison": 0,
        "Weakness": 0,
        "Paralysis": 0,
        "LifeStatus": 0
    },
    {
        "Strength": 0,
        "Intelligence": 0,
        "Defense": 0,
        "Resistance": 0,
        "Accuracy": 0,
        "Agility": 0,
        "Speed": 0,
        "CurrentAP": 0,
        "CurrentHP": 0,
        "Affinity": 0,
        "Poison": 0,
        "Weakness": 0,
        "Paralysis": 0,
        "LifeStatus": 0
    },
    {
        "Strength": 0,
        "Intelligence": 0,
        "Defense": 0,
        "Resistance": 0,
        "Accuracy": 0,
        "Agility": 0,
        "Speed": 0,
        "CurrentAP": 0,
        "CurrentHP": 0,
        "Affinity": 0,
        "Poison": 0,
        "Weakness": 0,
        "Paralysis": 0,
        "LifeStatus": 0
    }
]

答案 3 :(得分:0)

对于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 :(得分: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()