2017-10-02 2 views
0

J'ai une vidéo où la vue de face d'une voiture a été enregistrée. Le fichier est un .mp4 et je veux traiter les images individuelles afin que je puisse extraire plus d'informations (Objets, Lane Lines etc.). Le problème est, quand je veux créer une vidéo sur les fichiers traités, je reçois une erreur. Voici ce que je l'ai fait jusqu'à présent:Python: Créer une vidéo à partir d'images traitées

  1. a ouvert la vidéo avec cv2.VideoCapture() - fonctionne très bien
  2. les cadres Sauvés uniques de la vidéo avec cv2.imwrite() - Fonctionne bien
  3. Création une vidéo sur des images uniques avec cv2.VideoWriter() - fonctionne bien
  4. la vidéo avec Post-traitement cv2.cvtColor(), cv2.GaussianBlur() et cv2.Canny() - fonctionne bien
  5. Création d'une vidéo sur les images traitées - Ne fonctionne pas.

Voici le code i utilisé:

enter code here 
def process_image(image): 
    gray = functions.grayscale(image) 
    blur_gray = functions.gaussian_blur(gray, 5) 
    canny_blur = functions.canny(blur_gray, 100, 200) 

    return canny_blur 

process_on =0 
count =0 

video= cv2.VideoWriter("output.avi", cv2.VideoWriter_fourcc(*"MJPG"), 10, (1600, 1200)) 

vidcap = cv2.VideoCapture('input.mp4') 
success,image = vidcap.read() 

success = True 
while success: 
    processed = process_image(image) 
    video.write(processed) 

Ceci est l'erreur que je reçois:

OpenCV Error: Assertion failed (img.cols == width && img.rows == height*3) in cv::mjpeg::MotionJpegWriter::write, file D:\Build\OpenCV\opencv-3.2.0\modules\videoio\src\cap_mjpeg_encoder.cpp, line 834 Traceback (most recent call last): File "W:/Roborace/03_Information/10_Data/01_Montreal/camera/right_front_camera/01_Processed/Roborace_CAMERA_create_video.py", line 30, in video.write(processed) cv2.error: D:\Build\OpenCV\opencv-3.2.0\modules\videoio\src\cap_mjpeg_encoder.cpp:834: error: (-215) img.cols == width && img.rows == height*3 in function cv::mjpeg::MotionJpegWriter::write

Ma suggestion est la suivante: Les images normales ont 3 dimensions en raison de la couleur RGB champ. Les images traitées ont seulement une dimension. Comment puis-je ajuster cela dans la fonction cv2.VideoWriter.

Merci pour votre aide

Répondre

2

La VideoWriter() classe seulement écrit des images en couleur, pas en niveaux de gris à moins vous êtes sous Windows, qui il semble que vous pourriez juger par les chemins de votre sortie. Sous Windows, vous pouvez transmettre l'argument facultatif isColor=0 ou isColor=False au constructeur VideoWriter() pour écrire des images monocanal. Dans le cas contraire, la solution simple consiste à empiler simplement vos images en niveaux de gris en une image à trois canaux (vous pouvez utiliser cv2.merge([gray, gray, gray]) et écrire que

De l'VideoWriter() docs.

Parameters:

isColor – If it is not zero, the encoder will expect and encode color frames, otherwise it will work with grayscale frames (the flag is currently supported on Windows only).

Donc, par défaut, isColor=True et le drapeau ne peut pas être changé sur un système non-Windows donc simplement faire:.

video.write(cv2.merge([processed, processed, processed]) 

devrait vous rafistoler Même si la variante de Windows permet d'écrire des cadres en niveaux de gris, il peut être préférable d'utiliser cette deuxième méthode pour platfor. m indépendance.


également comme Zindarod mentions in the comments below il y a un certain nombre d'autres questions possibles avec votre code ici. Je suppose que vous avez collé du code modifié que vous n'aviez pas exécuté ici, ou que vous auriez modifié autrement ... si c'est le cas, veuillez ne poster que des exemples de code minimal, complete, and verifiable. D'abord et avant tout, votre boucle n'a pas de condition de fin, c'est donc indéfini. Deuxièmement, vous êtes en train de coder en dur la taille de l'image, mais VideoWriter() ne redimensionne pas simplement les images à cette taille. Vous devez fournir la taille de l'image que vous allez passer dans le VideoWriter().Redimensionnez le cadre à la même taille avant d'écrire pour être sûr, ou créez votre VideoWriter en utilisant la taille d'image définie dans votre périphérique VideoCapture() (en utilisant le .get() methods pour les propriétés de taille d'image).

En outre, vous lisez uniquement la première image en dehors de la boucle. C'était peut-être intentionnel, mais si vous voulez traiter chaque image de la vidéo, vous devrez bien sûr les lire en boucle, les traiter, puis les écrire.

Enfin, vous devriez avoir une meilleure erreur d'attraper dans votre code. Par exemple, voir le OpenCV "Getting Started with Video" Python tutorial. La section "Enregistrement d'une vidéo" a les vérifications et les balances appropriées: exécutez la boucle while le périphérique de capture vidéo est ouvert, et ne traiter et écrire la trame que si le frame a été lu correctement; puis une fois qu'il est hors des trames, la méthode .read() renverra False, ce qui vous permettra de sortir de la boucle, puis de fermer les dispositifs de capture et d'écriture. Notez la commande ici --- le périphérique VideoCapture() sera toujours "ouvert" même lorsque vous avez lu la dernière image, vous devez donc fermer la boucle en vérifiant le contenu de la trame.

+0

Il y a un certain nombre d'autres ambiguïtés dans son code, s'il vous plaît adressez-les dans votre réponse. Par exemple, la taille du cadre doit correspondre à la taille fournie au constructeur, la classe 'VideoWriter' ne redimensionne pas automatiquement le cadre pour correspondre au ctor. En outre, il écrit des cadres dans une boucle, mais en lisant les cadres en dehors de la boucle. – zindarod

+1

@Zindarod sonne bien, je l'ai fait. Je n'ai pas inclus ces suggestions à l'origine car l'OP a énuméré un ensemble d'actions de travail, donc j'ai supposé que OP l'utilisait probablement correctement mais juste collé un mauvais exemple. Cependant, il est possible que je me trompe, et il vaut également la peine d'écrire si d'autres personnes tombent sur la question, alors je vous remercie pour cette suggestion. –