9

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

编辑

修改我的代码后,它现在触发运行时 C++ 错误,但没有给出其他精度。根据这个答案,似乎使用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
4

5 回答 5

8

对于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()
于 2017-05-22T03:26:29.687 回答
4

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

于 2013-06-19T19:13:28.617 回答
3

我可以通过使用 if 语句来判断帧数何时达到cap.get(cv2.CAP_PROP_FRAME_COUNT),然后将帧数重置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 方法)会发生什么?

于 2015-01-11T18:20:57.490 回答
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()
于 2021-07-17T13:27:54.507 回答
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
}
于 2020-04-15T15:39:36.677 回答