簡體   English   中英

如何使用 OpenCV 和 Python 在視頻流中逐幀處理視頻圖像

[英]How to process images of a video, frame by frame, in video streaming using OpenCV and Python

我是 OpenCV 的初學者。 我想對上傳到我的服務器的視頻的幀進行一些圖像處理。 我只想讀取可用的幀並將它們寫入目錄中。 然后,等待視頻的另一部分上傳並將幀寫入目錄。 並且,我應該等待每一幀完全上傳然后將其寫入文件。

你能告訴我如何用 OpenCV (Python) 做到這一點嗎?

編輯 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 即使我等了很長時間,它也不會再捕獲幀了。

閱讀VideoCapture的文檔后。 我發現您可以告訴VideoCapture ,下次我們調用VideoCapture.read() (或VideoCapture.grab() )時要處理哪個幀。

問題在於,當您想要read()未准備好的幀時, 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

用這個:

import cv2
cap = cv2.VideoCapture('path to 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 opened windows

根據 OpenCV 3.0 及更高版本的最新更新,您需要在 Mehran 的代碼中更改屬性標識符,如下所示:

cv2.cv.CV_CAP_PROP_POS_FRAMES

cv2.CAP_PROP_POS_FRAMES

同樣適用於cv2.CAP_PROP_POS_FRAME_COUNT

希望能幫助到你。

在 openCV 的文檔中有一個逐幀獲取視頻的示例 它是用 C++ 編寫的,但很容易將示例移植到 python - 您可以搜索每個功能文檔以查看如何在 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;
}

這是我將如何開始解決這個問題:

  1. 創建視頻編寫器:

     import cv2.cv as cv videowriter = cv.CreateVideoWriter( filename, fourcc, fps, frameSize)

    在此處檢查有效參數

  2. 循環檢索 [1] 並寫入幀:

     cv.WriteFrame( videowriter, frame )

    寫框架文檔

[1] zenpoy 已經指出了正確的方向。 您只需要知道您可以從網絡攝像頭或文件中檢索圖像:-)

希望我理解正確的要求。

我找到的唯一解決方案不是將索引設置為前一幀並等待(然后 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

它完美無缺!

這是一個示例,其中 a.mp4 是視頻文件

import cv2
cap = cv2.VideoCapture('a.mp4')
count = 0
while cap.isOpened():
    ret,frame = cap.read()
    if not ret:
        continue
    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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM