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

Traitement d'images Discussion :

Flou en temps réel


Sujet :

Traitement d'images

  1. #1
    Membre actif
    Flou en temps réel
    Bonjour,

    j'aimerais savoir si il est possible de faire un effet de flou en temps réel sur une image de 1024x768.

    La seule solution que j'aie trouvé pour le moment est de dézoomer l'image puis de la zoomer avec un filtre bilinéaire, ce qui donne un effet de flou rapide mais n'est pas aussi beau qu'un flou gaussien.
    Je travaille en Java et la méthode que j'ai trouvée est assez rapide.

    Cependant je suis preneur de solutions au rendu plus esthétique et au moins aussi rapides.

    Pour le moment, j'obtiens des résultats de ce genre :

    avant :


    après :
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | www.anadoncamille.com
    | sylv.tournois.free.fr
    |

  2. #2
    Membre chevronné
    Flou en temps réel
    Bonjour,

    Il faut maîtriser le paramètre de floutage, c'est à dire la distance (a) en-deçà de laquelle les pixels les plus proches interviennent dans le calcul de la couleur locale.
    Les coefficients sont donnés, dans le cas le plus simple, par une loi parabolique de la forme;
    K(d) = 1 - (d2/a2) si (d2 < a2) sinon K(d) = 0 ;
    la fonction K(d) = (1 - (d2/a2)))2 présente une pente continue aux bornes de l'intervalle [-a; +a] .

    Chaque composante (i) de la nouvelle couleur locale ((1, 2, 3) = (r, v, b)) s'exprime en fonction de celles des pixels voisins par la combinaison linéaire:
    Pixel(x, y)[i] = Round(Somme(K(d)*Pixel(x', y')[i])/Somme(K(d))) .
    Compte tenu de la noirceur du fond, tu éviteras un assombrissement de l'image par le calcul de la moyenne quadratique;
    w = Somme(K(d)*Pixel(x', y')[i]2)/Somme(K(d));
    Pixel(x, y)[i] = Round(Sqrt(w)) .

    Pour la rapidité, c'est une autre histoire ... Le plus important est l'effet esthétique, que tu recherches.


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  3. #3
    Membre chevronné
    Flou en temps réel
    En y regardant de près, on s'aperçoit que ton procédé détériore l'image, probablement en établissant des moyennes sur des carrés (par la succession des opérations de zoom) alors que les calculs doivent être faits sur des domaines à contour circulaire.


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  4. #4
    Membre chevronné
    Flou en temps réel
    Voici ce que donne le floutage d'une image après réduction de ses dimensions (350x263):


    pour des valeurs du rayon égales à 2, 5, 8, 11 arêtes de pixels:


    Les coefficients sont calculés par la fonction parabolique, la plus simple.

    L'opération dure environ uns seconde; le délai est nettement plus long pour l'image d'origine.
    Il est proportionnel au produit Largeur*Hauteur*Rayon2 , en raison de l'intervention de quatre boucles imbriquées.


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  5. #5
    Membre actif
    N'y a-t-il pas des optimisations ou des astuces qui permettraient d'obtenir ce résultat avec une cadence de 25 images/s en 1024x768 ?
    J'ai des contraintes de temps, c'est pour cela que je sacrifie l'esthétique pour le moment.
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | www.anadoncamille.com
    | sylv.tournois.free.fr
    |

  6. #6
    Membre chevronné
    Flou en temps réel
    Citation Envoyé par anadoncamille Voir le message
    N'y a-t-il pas des optimisations ou des astuces qui permettraient d'obtenir ce résultat avec une cadence de 25 images/s en 1024x768 ? ...
    Traiter une image de semblables dimensions en 40 ms me paraît difficile ... seul un familier des logiciels de traitement d'images pourrait t'apporter des précisions.
    La cadence dont tu parles est celle d'une prise de vue cinématographique; ne s'agirait-il pas de cela ?
    Auquel cas il suffirait de modifier la mise au point de la caméra, au niveau de son objectif, pour obtenir le flou désiré. La transformation ne relèverait plus d'un traitement numérique, mais de l'optique physique.


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  7. #7
    Membre éclairé
    Filtrage pas net
    Bonjour,

    La solution proposée est une solution de type à réponse impulsionnelle (2D) finie. Elle permet un contrôle très fin de ce que l'on fait au prix de nombreux calculs donc de temps.

    Une autre approche inspirée des filtre à réponse impulsionnelle infinie consiste à parcourir l'image en serpentin en propageant une fraction d'un pixel sur les 2 suivants en x et en y. Arrivé au terme de l'image il faut faire le parcours inverse (avec une projection inversée également) pour annihiler les retards (décalages et anisotropie) du filtrage. Un traitement particulier du premier point peut être utile.

    Il n'y a pas séparation en image source et image cible : l'image cible est l'image source (une copie initiale peut être nécessaire si on veut conserver l'image originale).

    Si la proportion est une puissance de 2 (1/16 par exemple) il n'y a pas d'opération coûteuse en temps (mais ça limite sensiblement le contrôle).

    Chaque point n'étant sollicité que 2 fois le traitement est assez rapide pour un résultat intéressant sinon parfait.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  8. #8
    Membre actif
    Effectivement, je cherche une solution numérique ayant les mêmes performances qu'une solution optique. Ma solution actuelle fonctionne rapidement, mais n'a pas le même rendu qu'une solution optique. Cependant, jusqu'à trouver mieux, je m'en contenterai.

    Pour l'algorithme du serpentin, je crains qu'il ne soit pas aussi rapide que ma solution, mais je ne l'ai pas encore implémenté pour le tester. Serait-il possible de voir un rendu de son résultat ?
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | www.anadoncamille.com
    | sylv.tournois.free.fr
    |

  9. #9
    Membre expert
    Bonjour pour un adoucissement (assez) rapide gaussien tu peux te référer à ce site : http://blog.ivank.net/fastest-gaussian-blur.html

    Le flou le plus rapide c'est de faire une moyenne

    Ensuite à chaque itération tu ré-appliques le filtre sur l'image précédente, ce qui adoucira de plus en plus l'image.

    Voici par exemple une fonction en pascal que j'utilise pour effectuer un flou rapide lors d'animations en temps réel

    Code pascal :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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    Procedure TBZBitmapBlurFilters.FastBlur;
    Var
      x1, y1, x2, y2, XSteps, YSteps, w, h: Integer;
      DstColor: TBZColor;
      xx, yy, totalsize, nextLineInc: Integer;
      Line0, Line2, PixelPtr, MaskPtr : PBZColor;
      AColor, AColor1, AColor0, AColor2: TBZColor;
      Delta : Single;
    Begin
      nextlineInc := 0;
      TotalSize := 0;
      x1 := 0;
      y1 := 0;
      x2 := 0;
      y2 := 0;
      w := 0;
      h := 0;
      getClippingBoundInfos(x1, y1, x2, y2, w, h, totalsize, nextLineInc); // Permet de calculer les incréments
      Line0 := OwnerBitmap.GetPixelPtr(X1, Y1);
      PixelPtr := OwnerBitmap.GetPixelPtr(X1, Y1 + 1);
      Line2 := OwnerBitmap.GetPixelPtr(X1, Y1 + 2);
      XSteps := (x2 - x1) - 2;
      YSteps := (y2 - y1) - 2;
      totalsize := (XSteps * YSteps);
      Inc(XSteps);
      xx := 0;
      yy := 0;
        While yy < TotalSize Do // TotalSize nombre de pixel total = Largeur*hauteur
        Begin
          AColor1 := PBZColor(PixelPtr + 1)^;
          AColor := PBZColor(PixelPtr - 1)^;
          AColor0 := PBZColor(Line0)^;
          AColor2 := PBZColor(Line2)^;
     
          DstColor.Red := (AColor0.Red + AColor2.Red + AColor.Red + AColor1.Red) Shr 2;
          DstColor.Green := (AColor0.Green + AColor2.Green + AColor.Green + AColor1.Green) Shr 2;
          DstColor.Blue := (AColor0.Blue + AColor2.Blue + AColor.Blue + AColor1.Blue) Shr 2;
          // Alpha
          DstColor.Alpha := AColor0.Alpha;
     
          PixelPtr^ := DstColor;
          Inc(PixelPtr);
          Inc(Line0);
          Inc(Line2);
          Inc(xx);
          If xx > XSteps Then
          Begin
            xx := 0;
            Inc(PixelPtr, NextLineInc);
            Inc(Line0, NextLineInc);
            Inc(Line2, NextLineInc);
          End;
          Inc(yy);
        End;
      End;
     
    End;
    { Note TBZColor = Record Red, Green, Blue, Alpha : Byte End; }



    Autre solution passer par OpenGL/DirectX/Vulkan en utilisant un shader

    Et une autre solution serait de pré-calculer le nombre d'image dont tu as besoin pour ton animation

    A+

    Jérôme
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  10. #10
    Membre actif
    Merci pour toutes ces solutions. Certaines sont assez complexes, mais performantes. Je vais voir ce que je vais faire.
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | www.anadoncamille.com
    | sylv.tournois.free.fr
    |

  11. #11
    Membre expert
    Salut avant hier en faisant quelques recherche je suis tombé sur ce site :
    https://badassjs.com/post/1298940200/stackblur et la http://www.quasimondo.com/StackBlurF...kBlurDemo.html présentant 3 différents algorithmes très intéressants
    surtout celui-ci http://www.quasimondo.com/BoxBlurFor...tBlurDemo.html

    A+

    Jérôme
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  12. #12
    Membre actif
    Merci pour ces algorithmes. En attendant de coder une des méthodes mentionnées, j'utilise la méthode que j'ai décrite en début de discussion, en y ajoutant une étape de flou simple sur l'image en taille réduite. Pour le moment c'est suffisant. Le flou n'est pas parfait mais met en valeur la partie nette de l'image. Voici un résultat :

    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | www.anadoncamille.com
    | sylv.tournois.free.fr
    |