web-dev-qa-db-ja.com

Opencv 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を返します!そして、たとえ私が長い間待っていても、それはもうフレームをキャプチャしません。

38
Mehran

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
46
Mehran

これを使って -

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
12
prtkp

OpenCV 3.0以降の最新の更新プログラムによると、MehranのコードでProperty Identifiersを次のように変更する必要があります。

cv2.cv.CV_CAP_PROP_POS_FRAMES

cv2.CAP_PROP_POS_FRAMES

cv2.CAP_PROP_POS_FRAME_COUNTにも同じことが当てはまります。

それが役に立てば幸い。

8
srihegde

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;
}
7
zenpoy

これは私がこれを解決し始める方法です:

  1. ビデオライターを作成します。

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

    有効なパラメーターについてはこちらをご覧ください

  2. ループして取得し[1]、フレームを書き込みます。

    cv.WriteFrame( videowriter, frame )
    

    WriteFrame doc

[1] zenpoyはすでに正しい方向を指していました。あなたはウェブカメラまたはファイルから画像を取得できることを知っている必要があります:-)

要件が正しいことを理解したことを願っています。

2
Robert Caspary

私が見つけた唯一の解決策は、インデックスを前のフレームに設定して待機することではなく(その後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

そして、それは完全に機能します!

2