IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Open CV et extraction d'images depuis vidéo


Sujet :

Python

  1. #1
    Invité
    Invité(e)
    Par défaut Open CV et extraction d'images depuis vidéo
    Salut !

    Petite question ayant un faible rapport à python...

    J'utilise opencv pour extraire des images d'une vidéo, pourquoi la qualité est-elle moins bonne ?

    Nom : Sans titre.png
Affichages : 500
Taille : 706,9 Ko

    J'ai essayé différents formats d'images (jpg, png, bmp, tiff) sans réussir à avoir mieux que ça. Le fondu est dégueulasse et la luminosité sur les particules est plus intense.

    Le code choppé sur internet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    # Importing all necessary libraries
    import cv2
    import os
     
    # Read the video from specified path
    cam = cv2.VideoCapture("Particles - 72556.mp4")
     
    try:
     
        # creating a folder named data
        if not os.path.exists('data'):
            os.makedirs('data')
     
    # if not created then raise error
    except OSError:
        print ('Error: Creating directory of data')
     
    # frame
    currentframe = 0
     
    while(True):
     
        # reading from frame
        ret,frame = cam.read()
     
        if ret:
            # if video is still left continue creating images
            name = './data/frame' + str(currentframe) + '.png'
     
            # writing the extracted images
            cv2.imwrite(name, frame)
     
            # increasing counter so that it will
            # show how many frames are created
            currentframe += 1
        else:
            break
     
    # Release all space and windows once done
    cam.release()
    cv2.destroyAllWindows()
    PS : Oops j'en oublie d'être poli !
    Merci d'avance.

  2. #2
    Membre actif
    Homme Profil pro
    Animateur Numérique
    Inscrit en
    Février 2013
    Messages
    143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Animateur Numérique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Février 2013
    Messages : 143
    Par défaut
    Salut,
    C'est peut-être dû à la compression, de mémoire Open CV compresse l'image PNG par défaut à 3 (0 pas de compression, 9 compression max)

    Tente ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cv2.imwrite(name, frame, [cv2.IMWRITE_PNG_COMPRESSION, 0])

  3. #3
    Invité
    Invité(e)
    Par défaut
    Hum, pas de différence avec ce paramètre... J'ai essayé d'autres paramètres, pas mieux.

    J'ai essayé de rajouter des paramètres dans la ligne : cv2.VideoCapture("Particles - 72556.mp4") selon : https://docs.opencv.org/4.x/d4/d15/g...139bf7c4f5704d mais je dois pas avoir la bonne version d'Open CV ou que sais-je car la fonction n'a que 2 paramètres et non 3...

    PS : J'ai mis à jour open cv, je peux saisir un 3 ème argument mais il n'y a quasiment rien qui marche...
    Dernière modification par Invité ; 19/06/2022 à 22h30.

  4. #4
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 211
    Par défaut
    Hello,
    Citation Envoyé par Diablo76 Voir le message
    Salut,
    C'est peut-être dû à la compression, de mémoire Open CV compresse l'image PNG par défaut à 3 (0 pas de compression, 9 compression max)
    Attention une image PNG est toujours lossless (sans perte de qualité) même avec de la compression. Le gain avec de la compression est nettement moins important qu'en JPEG sauf si on a des zones d'image importantes avec la même valeur de couleur.
    J'ai fait différents essais avec ffmpeg, vlc, opencv. Avec GIMP en utilisant les calques avec le mode Différence, il apparaît que la capture d'écran dans VLC est différente de celle faite par ffmpeg. Celle-ci paraît moins lumineuse que celle en opencv alors qu'avec le mode différence on ne lvoit pas de différences.
    Voici la différence entre vlc et opencv :
    Nom : DiffVlcFFmpeg.PNG
Affichages : 428
Taille : 363,9 Ko

    Quand on visualise alternativement les deux images, on dirait qu'il y a un décalage, comme si ce n'était pas tout à fait la même trame.

    [EDIT] Vidéo récupérée ici avec une résolution de 1920x1080 ( 3.8 Mo) . Les tests on été effectués avec cette résolution.
    Pour extraire toutes les images de la vidéo avec VLC utiliser le filtre Scène. Il y a moins de différence entre la première image extraite avec ce procédé et opencv que dans l'image de différence de cette discussion.

    Ami calmant, J.P

  5. #5
    Invité
    Invité(e)
    Par défaut
    Merci Juju !

    Du coup tu aurais une idée pour avoir le rendu de VLC ?

    J'ai essayé du post-traitement avec ce genre de chose :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
        ret,frame = cam.read()
        #frame = cv2.convertScaleAbs(frame, frame, -0.5, 0)
        for c in np.arange(0, 1.5, 0.1):
            for b in np.arange(-1, 1, 0.1):
                output = cv2.convertScaleAbs(frame, c, b)
                #Original = image VLC
                dist = np.linalg.norm(original-output)
                distances.append(dist)
                outputs.append(output)
                cb.append((c,b))
     
        closest = min(distances)    
        index = distances.index(closest)
        print(index,'-',closest,'c :',cb[index][0],'b :',cb[index][1])
        output = outputs[index]
    Mais ça me fait n'importe quoi...

  6. #6
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 211
    Par défaut
    tu peux essayer de voir ce que cela donne avec le module pyffmpeg :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    from pyffmpeg import FFmpeg
    ff = FFmpeg()
    ff.options("-i D://tmp/Particles.mp4 -ss 00:00:00 -vframes 1 d://tmp/output.png")
    moi j'ai une différence de luminosité et de légères différences surtout sur les bords de l'objet vert par rapport à vlc.
    A voir si cela a rapport avec le codec utilisé pour le décodage du mp4.

  7. #7
    Invité
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ImportError: cannot import name 'win32' from 'pyffmpeg.static.bin.win32' (C:\Python39\lib\site-packages\pyffmpeg\static\bin\win32\__init__.py)
    J'ai été jeté un oeil dans __init__.py :


    J'ai essayé SimpleCV, l'import du module ne marche même pas...

  8. #8
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 211
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ImportError: cannot import name 'win32' from 'pyffmpeg.static.bin.win32' (C:\Python39\lib\site-packages\pyffmpeg\static\bin\win32\__init__.py)
    J'ai été jeté un oeil dans __init__.py :
    -->
    Nom : win32.png
Affichages : 400
Taille : 14,3 Ko

    win32.py contient du binaire (en particulier le binaire ffmpeg)

  9. #9
    Invité
    Invité(e)

  10. #10
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 211
    Par défaut
    j'utilise la version 2.1 de pyffmpeg : la version 2.3 ne contient pas le binaire pour windows ( la 2.2 apparemment le contient mais j'ai pris la 2.1 car plus petite en taille)

  11. #11
    Invité
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ERROR: Could not find a version that satisfies the requirement 2.1 (from versions: none)
    ERROR: No matching distribution found for 2.1
    Bon pas grave... Je vais peut-être coder un truc à l'arrache totale ! Du genre faire des imprimes écrans de VLC de toutes les images avec pynput pendant que je repasse mes caleçons ! ^^

    PS : Merci pour l'aide
    PS2 : Ah merde j'ai oublié que VLC buggue quand on fait plus de X fois "Image suivante" ! Y en a marre !!!
    PS 3 : 2.1.0 marche po non plus

  12. #12
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 211
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ERROR: Could not find a version that satisfies the requirement 2.1 (from versions: none)
    ERROR: No matching distribution found for 2.1
    La version à installer est la 2.1.0 ( en fait la 2.1 n'existe pas )

  13. #13
    Invité
    Invité(e)
    Par défaut
    Bon après moult essais, voici un résultat qui semble plus joli à première vue avec CAP_MSMF .

    Les moult essais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    import cv2
     
    codecs = (cv2.CAP_ANY, cv2.CAP_VFW, cv2.CAP_V4L, cv2.CAP_V4L2, cv2.CAP_FIREWIRE,
              cv2.CAP_FIREWARE, cv2.CAP_IEEE1394, cv2.CAP_DC1394, cv2.CAP_CMU1394,
              cv2.CAP_QT, cv2.CAP_UNICAP, cv2.CAP_DSHOW, cv2.CAP_PVAPI, cv2.CAP_OPENNI,
              cv2.CAP_OPENNI_ASUS, cv2.CAP_ANDROID, cv2.CAP_XIAPI, cv2.CAP_AVFOUNDATION,
              cv2.CAP_GIGANETIX, cv2.CAP_MSMF, cv2.CAP_WINRT, cv2.CAP_INTELPERC, cv2.CAP_REALSENSE,
              cv2.CAP_OPENNI2, cv2.CAP_OPENNI2_ASUS, cv2.CAP_OPENNI2_ASTRA, cv2.CAP_GPHOTO2,
              cv2.CAP_GSTREAMER, cv2.CAP_FFMPEG, cv2.CAP_IMAGES, cv2.CAP_ARAVIS, cv2.CAP_OPENCV_MJPEG,
              cv2.CAP_INTEL_MFX, cv2.CAP_XINE, cv2.CAP_UEYE)
     
    for codec in codecs :
        try:
            camera = cv2.VideoCapture(r'Particles - 72556.mp4', codec)
            while True:
                retval, im = camera.read(0)
                if not retval:
                    break
                for X in dir(cv2):
                    if getattr(cv2, X) == codec and X.startswith('CAP'):
                        cv2.imwrite(f"data/frame_0_{X}.png", im)
                break
        except:
            for X in dir(cv2):
                if getattr(cv2, X) == codec and X.startswith('CAP'):
                    print('Bug codec :', X)
    Nom : Sans titre.png
Affichages : 386
Taille : 1,24 Mo

Discussions similaires

  1. Réponses: 3
    Dernier message: 16/12/2015, 15h30
  2. Extraction des images à partir d'une vidéo AVI
    Par GPA13 dans le forum Images
    Réponses: 1
    Dernier message: 27/02/2013, 14h08
  3. [Débutant] extraction d'images à partir d'une vidéo
    Par pacem dans le forum Images
    Réponses: 9
    Dernier message: 14/06/2009, 00h21
  4. Extraction d'image depuis une animation SWF
    Par rori dans le forum Flash
    Réponses: 2
    Dernier message: 30/08/2007, 16h57
  5. extraction d'images jpeg à partir d'une vidéo
    Par crazyangelbones dans le forum Multimédia
    Réponses: 3
    Dernier message: 25/05/2007, 00h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo