wake-up-neo.com

So verarbeiten Sie Bilder eines Videos Frame für Frame im Video-Streaming mit Opencv python

Ich bin ein Anfänger in OpenCV. Ich möchte einige Bildbearbeitungen an den Frames eines Videos durchführen, das auf meinen Server hochgeladen wird. Ich möchte nur die verfügbaren Frames lesen und in ein Verzeichnis schreiben. Warten Sie, bis ein anderer Teil des Videos hochgeladen ist, und schreiben Sie die Frames in das Verzeichnis. Und ich sollte warten, bis jedes Bild vollständig hochgeladen ist, und es dann in eine Datei schreiben.

Kannst du mir sagen, wie ich das mit OpenCV (Python) machen kann?

Edit 1: Ich habe diesen Code zum Aufnehmen des Videos aus einer Datei geschrieben, während am Ende der Datei neue Daten angehängt werden. Mit anderen Worten, die Datei out.mp4 Ist kein vollständiges Video, und ein anderes Programm schreibt neue Frames darauf. Ich warte darauf, dass das andere Programm neue Frames schreibt, diese dann liest und anzeigt.

Hier ist mein Code:

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

Das Problem ist also der cap.grab() -Aufruf! Wenn es keinen Frame gibt, wird False zurückgegeben! Und es werden keine Frames mehr aufgenommen, auch wenn ich lange warte.

38
Mehran

Nach dem Lesen der Dokumentation von VideoCapture . Ich habe herausgefunden, dass Sie VideoCapture mitteilen können, welcher Frame beim nächsten Aufruf von VideoCapture.read() (oder VideoCapture.grab() ).

Das Problem ist, dass, wenn Sie einen Frame read(), der nicht bereit ist, verwenden möchten, das VideoCapture -Objekt an diesem Frame hängen bleibt und niemals fortfährt. Sie müssen es also erzwingen, um wieder mit dem vorherigen Frame zu beginnen.

Hier ist der Code

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

benutze das -

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

Gemäß den neuesten Updates für OpenCV 3.0 und höher müssen Sie die Property Identifiers wie folgt im Code von Mehran ändern:

cv2.cv.CV_CAP_PROP_POS_FRAMES

zu

cv2.CAP_PROP_POS_FRAMES

und gleiches gilt für cv2.CAP_PROP_POS_FRAME_COUNT.

Ich hoffe es hilft.

8
srihegde

In der Dokumentation von openCV gibt es ein Beispiel , um Video Frame für Frame abzurufen. Es ist in c ++ geschrieben, aber es ist sehr einfach, das Beispiel nach python zu portieren - Sie können nach jeder Funktionsdokumentation suchen, um zu sehen, wie man sie in Python aufruft.

#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

So würde ich anfangen, das zu lösen:

  1. Erstellen Sie einen Video-Writer:

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

    Hier nach gültigen Parametern suchen

  2. Schleife, um [1] abzurufen und die Frames zu schreiben:

    cv.WriteFrame( videowriter, frame )
    

    WriteFrame doc

[1] Zenpoy zeigte bereits in die richtige Richtung. Sie müssen nur wissen, dass Sie Bilder von einer Webcam oder einer Datei abrufen können :-)

Hoffentlich habe ich die Anforderungen richtig verstanden.

2
Robert Caspary

Die einzige Lösung, die ich gefunden habe, ist, den Index nicht auf ein vorheriges Bild zu setzen und zu warten (dann hört OpenCV ohnehin auf, Bilder zu lesen), sondern die Aufnahme noch einmal zu initialisieren. So sieht es also aus:

cap = cv2.VideoCapture(camera_url)
while True:
    ret, frame = cap.read()

    if not ret:
        cap = cv.VideoCapture(camera_url)
        continue

    # do your processing here

Und es funktioniert perfekt!

2