Je suis débutant dans OpenCV. Je souhaite effectuer un traitement d'image sur les images d'une vidéo en cours de téléchargement sur mon serveur. Je veux juste lire les cadres disponibles et les écrire dans un répertoire. Et attendez qu'une autre partie de la vidéo soit téléchargée et écrivez les images dans le répertoire. Et je devrais attendre que chaque image soit complètement téléchargée, puis l'écrire dans un fichier.
Pouvez-vous me dire comment puis-je le faire avec OpenCV (Python)?
Edit 1: J'ai écrit ce code pour capturer la vidéo à partir d'un fichier, tandis que de nouvelles données sont ajoutées à la fin du fichier. En d'autres termes, le fichier out.mp4
N'est pas une vidéo complète et un autre programme écrit de nouvelles images dessus. Ce que je vais faire, c'est attendre que l'autre programme écrive de nouvelles images, puis les lise et les affiche.
Voici mon 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
Le problème est donc l'appel cap.grab()
! quand il n'y a pas de cadre, il retournera False
! Et il ne capturera plus d'images, même si j'attends longtemps.
Après avoir lu la documentation de VideoCapture
. Je pensais que vous pouviez dire à VideoCapture
, quelle image traiter lors de notre prochain appel à VideoCapture.read()
(ou VideoCapture.grab()
).
Le problème est que lorsque vous voulez read()
une image qui n'est pas prête, l'objet VideoCapture
reste bloqué sur cette image et ne continue jamais. Vous devez donc le forcer à recommencer à partir du cadre précédent.
Voici le 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
utilisez ceci -
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
Selon les dernières mises à jour pour OpenCV 3.0 et versions ultérieures, vous devez modifier le Property Identifiers comme suit dans le code de Mehran:
cv2.cv.CV_CAP_PROP_POS_FRAMES
à
cv2.CAP_PROP_POS_FRAMES
et de même pour cv2.CAP_PROP_POS_FRAME_COUNT
.
J'espère que ça aide.
Dans la documentation d'openCV, il existe un exemple pour obtenir une vidéo image par image. Il est écrit en c ++ mais il est très facile de porter l’exemple sur python - vous pouvez rechercher chaque documentation de fumction pour savoir comment l’appeler en 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;
}
Voici comment je commencerais à résoudre ceci:
Créer un graveur vidéo:
import cv2.cv as cv
videowriter = cv.CreateVideoWriter( filename, fourcc, fps, frameSize)
Boucle pour récupérer [1] et écrire les cadres:
cv.WriteFrame( videowriter, frame )
[1] zenpoy a déjà pointé dans la bonne direction. Vous devez juste savoir que vous pouvez récupérer des images depuis une webcam ou un fichier :-)
J'espère que j'ai bien compris les exigences.
La seule solution que j'ai trouvée n'est pas de définir l'index sur une image précédente et d'attendre (puis OpenCV arrête de lire les images, de toute façon), mais d'initialiser la capture une fois de plus. Donc, ça ressemble à ça:
cap = cv2.VideoCapture(camera_url)
while True:
ret, frame = cap.read()
if not ret:
cap = cv.VideoCapture(camera_url)
continue
# do your processing here
Et ça marche parfaitement!