как уменьшить непрозрачность границ маски (прозрачного изображения) в обработке?

Я собираюсь показать 2 слоя (изображение глубины из kinect и маску соответственно) в моем проекте обработки. В этом проекте я собираюсь скрыть области, недоступные пользователю, с помощью маски. Обратите внимание, что «маска» получает свои пиксели из фильма с именем «movie2» в моем коде.
Есть ли способ размыть границы пользователей, уменьшив непрозрачность границ маски?

Вот мой код:

    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);
    }

person Armin Afsharian Zadeh    schedule 13.02.2017    source источник
comment
Конечно, просто переберите граничные пиксели и установите их непрозрачность. Какая часть этого доставляет вам неприятности? Можете ли вы собрать минимально воспроизводимый пример, который пытается сделать это на одном жестко запрограммированном изображении вместо фильма? ?   -  person Kevin Workman    schedule 13.02.2017
comment
Конечно, код был отредактирован для ясности.   -  person Armin Afsharian Zadeh    schedule 13.02.2017


Ответы (1)


Есть несколько вещей, которые можно было бы улучшить:

  1. Нет необходимости загружать маску несколько раз в секунду в draw() (достаточно одного раза в настройках)
  2. Вы можете использовать функцию mask() для применения маски
  3. Вы можете управлять пользовательским изображением с прозрачными пикселями для маскирования и непрозрачными пикселями для пользовательских пикселей, которые вы можете отфильтровать, чтобы уменьшить границу (например, ERODE или BLUR через фильтр()

Другие примечания:

  • Встроенное размытие Processing может быть немного медленным, но вы можете использовать библиотеку OpenCV for Processing Грега Боренштейна у которого более быстрые фильтры (размытие, эрозия)
  • Если вы проверяете только userMap и вам не нужны координаты x, y, вы можете просто использовать плоский цикл вместо вложенного цикла и получить немного скорости.

Вот попытка проиллюстрировать приведенные выше пункты в виде кода, но имейте в виду, что это неполный/непроверенный:

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();
}
person George Profenza    schedule 14.02.2017
comment
Это очень хорошее решение. Однако, когда я собираюсь фильтровать userImage по алгоритму opencv, кажется, что он игнорирует альфа-каналы. Я использовал следующий код для фильтрации userImage: opencv.loadImage(userImage); opencv.blur(3); размытие = opencv.getSnapshot(); изображение (размытие, 0,0); - person Armin Afsharian Zadeh; 17.02.2017
comment
любое другое решение? opencv игнорирует альфа-канал, поэтому это решение здесь не будет эффективным. - person Armin Afsharian Zadeh; 25.02.2017