首页 文章

如何使用Opencv python在视频流中逐帧处理视频图像

提问于
浏览
35

我是OpenCV的初学者 . 我想对正在上传到我的服务器的视频帧进行一些图像处理 . 我只是想读取可用的帧并将它们写在目录中 . 等待视频的其他部分上传并将帧写入目录 . 我应该等待每个帧完全上传然后将其写入文件 .

你能告诉我怎样才能用OpenCV(Python)做到这一点?

Edit 1: 我编写了这段代码,用于从文件中捕获视频,而新数据则附加在文件的末尾 . 换句话说, out.mp4 文件不是完整的视频,另一个程序正在其上写入新的帧 . 我要做的是,等待其他程序写入新帧然后读取它们并显示它们 .

这是我的代码:

import cv2
cap = cv2.VideoCapture("./out.mp4")

while True:
    if cap.grab():
        flag, frame = cap.retrieve()
        if not flag:
            continue
        else:
            cv2.imshow('video', frame)
    if cv2.waitKey(10) == 27:
        break

所以问题是 cap.grab() 电话!当没有框架时它将返回 False !即使我等了很长时间,它也不再捕捉帧了 .

6 回答

  • 2

    阅读VideoCapture的文档后 . 我想你可以告诉 VideoCapture ,下次我们调用VideoCapture.read()(或VideoCapture.grab())时要处理哪个帧 .

    问题是当你想要一个没有准备好的帧时, VideoCapture 对象卡在那个帧上并且永远不会继续 . 所以你必须强制它从前一帧开始 .

    这是代码

    import cv2
    
    cap = cv2.VideoCapture("./out.mp4")
    while not cap.isOpened():
        cap = cv2.VideoCapture("./out.mp4")
        cv2.waitKey(1000)
        print "Wait for the header"
    
    pos_frame = cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
    while True:
        flag, frame = cap.read()
        if flag:
            # The frame is ready and already captured
            cv2.imshow('video', frame)
            pos_frame = cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
            print str(pos_frame)+" frames"
        else:
            # The next frame is not ready, so we try to read it again
            cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, pos_frame-1)
            print "frame is not ready"
            # It is better to wait for a while for the next frame to be ready
            cv2.waitKey(1000)
    
        if cv2.waitKey(10) == 27:
            break
        if cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES) == cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT):
            # If the number of captured frames is equal to the total number of frames,
            # we stop
            break
    
  • 7

    用这个 -

    import cv2
    cap = cv2.VideoCapture('path of video file')
    count = 0
    while cap.isOpened():
        ret,frame = cap.read()
        cv2.imshow('window-name',frame)
        cv2.imwrite("frame%d.jpg" % count, frame)
        count = count + 1
        if cv2.waitKey(10) & 0xFF == ord('q'):
            break
    
    
    cap.release()
    cv2.destroyAllWindows()  # destroy all the opened windows
    
  • 44

    在openCV的文档中,有一个example用于逐帧获取视频 . 它是用c编写的,但将示例移植到python非常容易 - 您可以搜索每个fumction文档以查看如何在python中调用它们 .

    #include "opencv2/opencv.hpp"
    
    using namespace cv;
    
    int main(int, char**)
    {
        VideoCapture cap(0); // open the default camera
        if(!cap.isOpened())  // check if we succeeded
            return -1;
    
        Mat edges;
        namedWindow("edges",1);
        for(;;)
        {
            Mat frame;
            cap >> frame; // get a new frame from camera
            cvtColor(frame, edges, CV_BGR2GRAY);
            GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
            Canny(edges, edges, 0, 30, 3);
            imshow("edges", edges);
            if(waitKey(30) >= 0) break;
        }
        // the camera will be deinitialized automatically in VideoCapture destructor
        return 0;
    }
    
  • 11

    根据OpenCV 3.0及更高版本的最新更新,您需要在Mehran的代码中更改 Property Identifiers

    cv2.cv.CV_CAP_PROP_POS_FRAMES
    

    cv2.CAP_PROP_POS_FRAMES
    

    同样适用于 cv2.CAP_PROP_POS_FRAME_COUNT .

    希望能帮助到你 .

  • 2

    这就是我开始解决这个问题的方法:

    • 创建视频编写器:
    import cv2.cv as cv
    videowriter = cv.CreateVideoWriter( filename, fourcc, fps, frameSize)
    

    Check here for valid parameters

    • 循环检索[1]并写入帧:
    cv.WriteFrame( videowriter, frame )
    

    WriteFrame doc

    [1] zenpoy已经指出了正确的方向 . 您只需要知道您可以从网络摄像头或文件中检索图像:-)

    希望我理解这些要求是正确的 .

  • 7

    我找到的唯一解决方案是不将索引设置为前一帧并等待(然后OpenCV停止读取帧,无论如何),但是再次初始化捕获 . 所以,它看起来像这样:

    cap = cv2.VideoCapture(camera_url)
    while True:
        ret, frame = cap.read()
    
        if not ret:
            cap = cv.VideoCapture(camera_url)
            continue
    
        # do your processing here
    

    而且效果很好!

相关问题