Superposer des Images

MickMick Membre
Bonjour à  tous,



je me heurte à  un problème :

Je dois "superposer" un certain nombre d'images pour faire une "chronophotographie"

Je me bats avec les NSComposite et la transparence, mais c'est bof pour l'instant. (cf copie d'écran : on devine vaguement qu'une balle s'est déplacée...) La transparence est à  0.1 pour chaque image et le mode est NSCompositeSourceOver.



Avez-vous par hasard déjà  été confronté à  ce genre de problèmes ? Y a-t-il une astuce que je ne connais pas ?..

Réponses

  • DrakenDraken Membre
    juin 2012 modifié #2
    À vue de nez ta valeur alpha est trop importante. Pour "additionner" correctement une série d'image, alpha doit théoriquement être égal à  1/nb images.

    0.1 c'est pour 10 images.

    Pour un film de 2 seconde à  25 image/s il faut un alpha de 1/(2*25), c'est à  dire 0,02.

    C'est de la théorie, je n'ai jamais essayé de le faire concrétement.

  • CéroceCéroce Membre, Modérateur
    juin 2012 modifié #3
    Le résultat que tu obtiens est tout à  fait normal avec cette technique.

    Disons qu'on a 10 images, chaque image va donc participer pour 1/10 dans le résultat final. Il est donc normal que la balle soit peu visible. En fait, ce qu'on obtient est une moyenne.



    Pour avoir un meilleur résultat, il faut d'abord construire l'image de fond en ne conservant que les pixels qui sont communs à  toutes les images. (1)

    Ensuite, l'image de la balle est la différence entre l'image et l'image de fond. Il suffit d'appliquer toutes les images de balles sur le fond.



    (1) Pour simplifier, on peut utiliser l'image moyenne, le résultat final sera identique à  1/10 de balle près.
  • MickMick Membre
    juin 2012 modifié #4
    @draken : j'ai effectivement commencé par ça, avec un 1/nbImages. Après, je me suis dit qu'avec la superposition, l'image du fond devrait avoir un alpha de 1.0, tandis que celle qui est au-dessus un alpha plus petit, (mais combien ?) et bricolé une formule du genre "intérêts cumulés" en banque ! Marche pas bien



    @Ceroce : alors là  chapeau. Bien vu ! Je m'en vais essayer ça de suite ! Je commence par superposer toutes les images avec un "over", puis je reprends les images une à  une pour faire une différence. Juste une chose : comment faire techniquement ? J'utilise la méthode NSImage drawAtPoint ... operation: pour l'instant. (j'ai aussi essayé avec les layers). Faire l'image moyenne ok, mais faire la différence entre une image et l'image moyenne ?, puis comment "ajouter" la balle ? avec NSCompositeSourceOver ?



    Je ne suis pas doué en graphismes...
  • AliGatorAliGator Membre, Modérateur
    Ce lien vers la doc Apple devrait certainement t'aider

    Avec le "Difference Blend Mode" tu devrais pouvoir facilement obtenir l'image correspondant à  la différence de 2 images
  • MickMick Membre
    Merci Ali. Moi qui croyait m'en sortir sans tripoter quartz !
  • bonjour à  tous,



    Petit soucis :

    lorsque j'utilise le graphiccontext de ma vue, j'arrive à  bricoler. Mais j'ai besoin de créer mon bitmapcontext. et là , je sèche, même avec la doc, en particulier "bytesPerRow" et "bytesPerComponent".



    quelqu'un peut m'éclairer, au moins en donnant des valeurs standards où des exemples ??
  • MickMick Membre
    juillet 2012 modifié #8
    Bon, en fait, je viens de réussir à  comprendre, enfin je crois. En tout cas, ça y est, je sais créer une bitmapcontext, dessiner dedans, puis afficher cela dans une NSView.



    Pour mon cas, j'ai créé le bitmapContext ainsi :


    <br />
    <br />
    [color=#743fa4]CGContextRef[/color] leContexte=[color=#c02d9d]NULL[/color];[color=#743fa4]<br />
    CGColorSpaceRef[color=#000000] colorSpace=[/color][color=#40207c]CGColorSpaceCreateWithName[/color][color=#000000]([/color]kCGColorSpaceGenericRGB[color=#000000]);[/color][/color]<br />
    [color=#c02d9d]int[/color] width=([color=#c02d9d]int[/color])[[color=#c02d9d]self[/color] bounds].[color=#743fa4]size[/color].[color=#743fa4]width[/color]; //Euh, il y a surement mieux qu&#39;un cast non ?<br />
    [color=#c02d9d]int[/color] height=([color=#c02d9d]int[/color])[[color=#c02d9d]self[/color] bounds].[color=#743fa4]size[/color].[color=#743fa4]height[/color];<br />
    [color=#c02d9d]int[/color] bytePerRow=[color=#2f2fd0]8[/color]*width;<br />
    [color=#c02d9d]void[/color] *bitMapData=[color=#40207c]malloc[/color](bytePerRow*height);<br />
    leContexte=[color=#40207c]CGBitmapContextCreate[/color](bitMapData, width, height, [color=#2f2fd0]8[/color], bytePerRow, colorSpace, [color=#40207c]kCGImageAlphaPremultipliedFirst[/color]);<br />
    




    C'est quand même génial CoreGraphics ! Je découvre et m'émerveille...
  • MickMick Membre
    juillet 2012 modifié #9


    Pour "additionner" correctement une série d'image, alpha doit théoriquement être égal à  1/nb images




    En fait, ce n'est pas si simple. Après une petite réflexion (qui ressemble au phénomène d'absorption en physique !!), alpha n'est pas identique pour chaque image. Après calcul, l'image de fond doit avoir un alpha égal à  1, l'image en haut de la pile doit avoir un alpha égal à  1/N. L'image "i" doit avoir un alpha égal à  1/(N-i) (si la première image est l'image 0). On a alors les "contributions" de toutes les images identiques. Ceci m'a été utile pour faire l'image "moyenne" que j'envoie en PJ
  • Bon, voilà  une image pas trop mal obtenue par la méthode "Ali", à  savoir :

    Création d'une image "off" moyenne



    On dessine l'image moyenne

    Passage en revue de chaque image, à  laquelle on soustrait l'image moyenne

    En mode blend "screen", on dessine l'une après l'autre, par-dessus l'image moyenne, toutes les images précédentes.
  • Plus j'y pense, et plus je me rappelle de mes TPs d Physique de lycée.

    Je ne sais plus que logiciel on utilisait sous Windows, mais on effectuait pas une sorte de " blend " comme tu le fais.

    C'est potentiellement une piste pour toi je pense.

    On faisait ainsi :

    On prenait la première (ou la seconde image, une fois la belle assez décollée de la main).

    On sélectionnait la balle (centre), on lui donnait un rayon.

    Et image par image, on resélectionnait le centre de la balle (en supposant que le diamètre était le même à  chaque fois).

    Uniquement les cercles de sélection apparaissaient sur l'image finie...

    On évitait ainsi tout l'espèce de flou sur le reste de l'image, notamment dans ton cas avec la personne.
  • CéroceCéroce Membre, Modérateur
    'Mick' a écrit:
    Bon, voilà  une image pas trop mal obtenue par la méthode "Ali"


    Je sais bien qu'Ali répond juste à  beaucoup de questions, mais là , je suis un peu vexé quand même image/angry.gif' class='bbc_emoticon' alt='>:(' />



    Le résultat à  l'air pas mal, même si ton image est minuscule.
  • Oh là , honteux je suis !! image/unsure.png' class='bbc_emoticon' alt=' :* ' /> mille excuses à  Céroce !!

    J'ai amélioré un peu le truc à  l'aide des masques "couleur" de quartz 2D. Lorsque je fais la différence entre une inmage et l'image moyenne, tout est sensé être noir, sauf ce qui bouge. Y'a plus qu'à  mettre un masque sur ce qui est presque noir pour que cela devienne transparent, et ensuite ajouter les images une à  une en mode normal !



    J'ai ajouté des sliders pour que l'utilisateur ajuste manuellement. Ca marche, mais j'ai quelques soucis de performances : lorsque l'utilisateur change un paramètre, il faut reconstruire toutes les images ... c'est long si il y en a beaucoup.
  • AliGatorAliGator Membre, Modérateur
    A la limite met de côté les images sans leur masque, si les paramètres n'influent que sur les masques. Comme ça tu n'auras qu'à  prendre chaque image de différence (inimage - moyenne) et appliquer juste le masque couleur dessus, au lieu de recalculer l'image moyenne + les diverses inimage avant...
  • MickMick Membre
    juillet 2012 modifié #15
    L'image



    Ok pour l'astuce. Je vais essayer.

    Merci
  • A y est, c'est beaucoup plus rapide en conservant les images sans les masques quelque part au lieu de les recréer.



    En tout cas, merci à  tous de vos lumières !!
Connectez-vous ou Inscrivez-vous pour répondre.