ダウンロード

filewin_BgSub_JMyron.zip

環境

MacOSX 10.4.3
processing0090

プログラム

//
// ウィンドウの左はムービー、
// ウィンドウの右推測した背景画像
//     Emi TAMAKI 2005.11.21
//

import JMyron.*;

JMyron movie;
PImage back;
PImage prev;

int Th = 83;
float alph = 0.020; 
float r, g, b;  
int dis, ans;
int sakai;

//--SetUp   -----/////////////////////////
void setup(){
size(400, 200);
sakai = width/2;
movie = new JMyron();
movie.start(width/2, height);
movie.findGlobs(0);
back = new PImage(width/2, height);
prev = new PImage(width/2, height);
//sleep使えるかも
for(int i=0;i<15;i++){
  movie.update();
  int[] movimg = movie.image();
  loadPixels();
  SetPixels2(movimg, back, prev); 
 }
}

//--Draw   -----//////////////////////////
void draw(){
/*--画像更新部分1---------------*/
int dimension = (200*200);
movie.update();
int[] movimg = movie.image();
loadPixels();

 /*--動画像処理部分--------------*/
for(int i=0; i< height*width/2; i++){
  dis = GetDistance(movimg, prev, i);
  if(dis < Th){
      r = (alph*red(movimg[i]) + (1.0 - alph)*red(back.pixels[i]));
      g = (alph*green(movimg[i]) + (1.0 - alph)*green(back.pixels[i])); 
      b = (alph*blue(movimg[i]) + (1.0 - alph)*blue(back.pixels[i]));
      back.pixels[i] = color(r, g, b); 
      }     
}
/*--表示部分-------------------*/
 for(int i=0;i<height*width;i++){
   if(i%width>=sakai){
     pixels[i] = back.pixels[i%width - sakai + i/width*back.width];
   }else{
     pixels[i] = movimg[i%width + i/width*back.width];
   }
 }
  
 SetPixels(movimg, prev);        //次のフレーム処理の時に使うやつ  
 /*--画像更新部分2---------------*/
 updatePixels();
}

//--SetPixels 動画像から画像を1枚   -----////////////////
void SetPixels(int[] M, PImage P){
  for(int i=0;i<(P.height*P.width);i++){
        r = red(M[i]); 
        g = green(M[i]);
        b = blue(M[i]);
        P.set(i%P.width, i/P.height, color(r,g,b)); 
  }
}
  
//--SetPixels2 動画像から画像を2枚   -----////////////////
void SetPixels2(int[] M, PImage P1, PImage P2){
  for(int i=0;i<(P1.height*P1.width);i++){
        r = red(M[i]); 
        g = green(M[i]);
        b = blue(M[i]);
         P1.set(i%P1.width, i/P1.height, color(r,g,b)); 
         P2.set(i%P2.width, i/P2.height, color(r,g,b)); 
   }
}   

//--GetDistance 画像のピクセルデータの距離を測定する----//////
int GetDistance(int[] M, PImage P, int n){
 r = int(abs(red(M[n]) - red(P.pixels[n])));
 g = int(abs(green(M[n]) - red(P.pixels[n])));
 b = int(abs(blue(M[n]) - blue(P.pixels[n])));
 ans = int(r + g + b);
 return ans;
}

実行結果

1.jpg
左が動画で、右が推測した背景画像

コメント

  • GetDistance?() は結局これで問題ないですか?
    現時点での実験範囲内で問題があるかというレベルでの判断で良いです. -- nal 2005年11月21日 16:20:54 (月)
  • 背景から手を切り出すってのはここの処理と同じだと思いますが,
    処理の重さ的にこの手法で問題ないかどうかも判断してみてください. -- nal 2005年11月21日 16:21:40 (月)
  • しきい値関係の
    int Th = 83; 
    float alph = 0.020;
    はそんなにクリティカルな調整をしなくても結構動くの? 
    それともかなり調整しました? -- 當間? 2005年11月21日 16:22:23 (月)
  • 処理フローとしては,
    ある一定上 GetDistance?() での距離が離れている場合に推定するようになってるみたいだけど,
    結果画像を見た感じだと「指が無い場所も推定されてる」ように見えます(=処理が重そう).
    これは処理結果的には問題ないレベルですか?
    (逆に言うと,どの程度の精度があればOKですか?  また,それを確認する為の実験設定は?)
    • 當間? 2005年11月21日 17:26:42 (月)
  • 処理の重さという観点からは,処理がちょっと重くても,
    カメラ移動時等大幅に背景変わるとき用の処理だから問題ないレベル? -- 當間? 2005年11月23日 10:15:29 (水)