2017-02-13 3 views
1

Je vais montrer 2 couches (profondeur image de kinect et un masque, respectivement) dans mon projet de traitement. Dans ce projet, je vais cacher les zones où il n'y a pas d'utilisateur disponible en utilisant un masque. Notez que "mask" obtient ses pixels d'un film nommé "movie2" dans mon code.
Existe-t-il un moyen d'estomper les frontières des utilisateurs en réduisant l'opacité des bordures de masque?comment réduire l'opacité des frontières de masque (image transparente) dans le traitement?

Voici mon code:

import SimpleOpenNI.*; 
PImage mask,depth; 
SimpleOpenNI kinect; 
int[] userMap; 

void setup(){ 
    kinect = new SimpleOpenNI(this); 
    size(640,480); 
    kinect.enableDepth(); 
    kinect.enableUser(); 
     } 

     void draw(){ 
     kinect.update(); 
     depth=kinect.depthImage(); 
     userMap = kinect.userMap(); 
     image(depth,0,0); 
     mask=loadImage("mask.jpg"); 
     mask.loadPixels(); 
    for (int y=0; y<480; y++) { 
      for (int x=0; x<640; x++) { 
      int index = x + y *640; 
      if (userMap[index]!= 0) { 
      mask.pixels[index]=color(0,0,0,0); 
      } 
      } 
     } 
     mask.updatePixels(); 
     image(mask,0,0); 
    } 
+0

Bien sûr, juste itérer sur les pixels de bordure et définir leur opacité. Quelle partie de cela vous donne des ennuis? Pouvez-vous mettre en place un [mcve] qui essaie de le faire sur une seule image codée en dur au lieu d'un film? –

+0

Bien sûr, le code a été modifié par souci de clarté. –

Répondre

0

Il y a quelques choses qui pourraient être améliorés:

  1. Pas besoin de charger le masque plusieurs fois par seconde en tirage au sort() (une fois dans la configuration sera suffisant)
  2. Vous pouvez utiliser la fonction mask() pour appliquer un masque
  3. Vous pouvez gérer un une image d'utilisateur personnalisée avec des pixels transparents pour le masquage et des pixels opaques pour les pixels d'utilisateur que vous pouvez filtrer pour réduire la bordure (par ex. ERODE ou BLUR via filter()

Autres notes:

  • de flou intégré de traitement peut être un peu lent, mais vous pouvez utiliser Greg Borensteinn's OpenCV for Processing library qui a plus rapide des filtres (flou, érode)
  • Si vous Vérifiez seulement la userMap et vous n'avez pas besoin de coordonnées x, y, vous pouvez simplement utiliser une boucle plate au lieu d'une boucle imbriquée et gagner un peu de vitesse.

est ici un coup de couteau à illustrer les points ci-dessus code, mais nu à l'esprit cette incomplet/non testé:

import processing.video.*; 

class effect2{ 
    PImage mask; 

    int[] userMap; 
    PImage userImage; 

    int numPixels; 

    effect2(){ 
    //movie2 = new Movie(this,"MOVIE_2_PATH_HERE");//might be initialised somewhere 
    movie2.play(); 
    //initialize image once 
    userImage = createImage(640,480,ARGB); 
    userImage.loadPixels(); 

    numPixels = userImage.width * userImage.height; 

    userMap = new int[numPixels]; 
    } 

    void drawing(){ 
    //kinect.update(); is called at some point 

    image(depth,0,0); 

    //update user map 
    kinect.userMap(userMap); 
    //update user image based on user map 
    //flat (1D) for loop is faster than nested (2D) for loop 
    for(int i = 0; i < numPixels; i++){ 
     if (userMap[i] == 0) { 
      userImage.pixels[i] = 0x00000000;//transparent black 
     }else{ 
      userImage.pixels[i] = 0xFFFFFFFF;//opaque white 
     } 
    } 
    userImage.updatePixels(); 

    //filter/blur as needed 
    //I recommend using https://github.com/atduskgreg/opencv-processing for faster blur (and other filters) 
    userImage.filter(BLUR,2); 

    //apply mask 
    movie2.mask(userImage,0,0); 

    //preview mask 
    image(userImage,0,0,64,48); 
    } 

} 
//the movie is updated too 
void movieEvent(Movie m){ 
    m.read(); 
} 
+0

C'est une très bonne solution. Cependant, quand je vais filtrer userImage par l'algorithme d'opencv, il semble qu'il ignore les canaux alpha. J'ai utilisé le code suivant pour filtrer userImage: opencv.loadImage (userImage); opencv.blur (3); flou = opencv.getSnapshot(); image (flou, 0,0); –

+0

une autre solution? opencv ignore le canal alpha, donc cette solution ne serait pas efficace ici. –