« 【Processing】 GSVideoでWebカメラを使う | トップページ | 【Processing】二値化した画像のラべリング »

2014/02/01

【Processing】色識別

 昼間なのに眠気を覚え、3時間近く寝てしまいました。     ねむい・・・
  
 ということで前回Webカメラを使えるようにしたので、今回はWebカメラの画像から色を抽出してみます。
 機能としては以下。

 ・画面に映っている目標物をマウスでクリックして色を抽出する。
 ・抽出された色と同じ色をすべて抽出し別画面にターゲットとして描画する。
 ・ターゲットの位置を認識し四角で囲む。

   プログラムはこちらを参考にさせていただきました。

 

◇test034
  実行環境:Processing 2.1.1
  Webカメラ:Logicool HD Pro Webcam C910

//test034
import codeanticode.gsvideo.*;

int w_img = 320;       
int h_img = 240;           
int p_text_size = 30;      
int fps = 15;

int tolerance=15;//色許容値用の変数(後で調整可)
color targetColor=color(255,0,0);//物体の色用の変数(後で変更可)

color white = color(255, 255, 255);

int x,y,x1,y1,x2,y2,x3,y3,x4,y4;//図形座標用変数
int xmin=w_img,xmax=0;//左端X座標、右端X座標
int ymin=h_img,ymax=0;//上端Y座標、下端Y座標 

int a=5;//余白
int b=15;//行間

boolean detection=false;//物体検知のフラグ 

GSCapture cam;

void setup() {
  size(w_img, h_img*2);  // 画面サイズの設定
  String[] cameras = GSCapture.list();
  if (cameras.length == 0){
    println("There are no cameras available for capture.");
    exit();
  } else {
    println("Available cameras:");
    for (int i = 0; i < cameras.length; i++) {
      println(cameras[i]);      // カメラの名
    }

    cam = new GSCapture(this, w_img, h_img, cameras[0]);
    cam.start();
  }
}

void draw() {
  frameRate(fps);      // フレームレートの設定

  fill(0);
  rect(0, h_img, w_img, h_img*2);

  if (cam.available()) {
    cam.read();       // カメラ画像を読み込んで
    set(0, 0,cam); // 画面に表示 

   detection=false;//物体検知のフラグをfalse(検知なし)にしておく

    for(int i=0 ; i< w_img*h_img ; i++)  //画面全体のピクセル数だけ繰り返し処理
    {

      //物体の色と各ピクセルの色の差を求める(RGB3色分)
      float difRed=abs(red(targetColor)-red(cam.pixels[i]));
      float difGreen=abs(green(targetColor)-green(cam.pixels[i]));
      float difBlue=abs(blue(targetColor)-blue(cam.pixels[i]));

      if (difRed < tolerance && difGreen < tolerance && difBlue < tolerance){
        detection=true;

        //左端、右端のX座標、上端、下端のY座標を導く
        //今回の値と今までの値を比較し、最小値、最大値を調べる
        xmin=min(i%w_img,xmin);//左端(X最小値)
        xmax=max(i%w_img,xmax);//右端(X最大値)
        ymin=min(i/w_img,ymin);//上端(Y最小値)
        ymax=max(i/w_img,ymax);//下端(Y最大値)

        set(i%w_img,i/w_img+h_img,targetColor);

      }
    }

    if(detection==true){//物体検知有りの場合

      x1=xmin;
      x2=xmax;
      y1=ymin;
      y2=ymax;

      //左端、右端、上端、下端の座標値を初期化しておく
      xmin=w_img;
      xmax=0;
      ymin=h_img;
      ymax=0;
    }
  }

  x3=x1-a;
  y3=y1+h_img-a;
  x4=x2-x1+a*2;
  y4=y2-y1+a*2;


  noFill();
  stroke(255);
  rect(x3,y3,x4,y4);

  String s;//物体検知有無表示の文字列変数
  if(detection==true){//物体検知有りの場合
    s="detected";//表示:「検知」
  }else{
    s="none";//表示:「なし」
  }

  //以下は各値の表示
  fill(targetColor);//指定した物体の色
  rect(0,h_img,b,b);//矩形表示
  text(tolerance+": "+s,20,h_img+b);//文字列表示(許容値:物体検知有無)
  text(x1+":"+y1+":"+x2+":"+y2,10,h_img+b*2);
  text(x3+":"+y3+":"+x4+":"+y4,10,h_img+b*3);

}


void mousePressed(){//クリックしたら
  //マウス座標上のピクセルの色(物体の色)を記憶しておく
  targetColor=cam.pixels[mouseX+mouseY*w_img];
}

void keyPressed(){

  if(key == ' '){
    exit();
  }
  if(key==CODED){
    if(keyCode==LEFT){//左キーを押した場合
      tolerance-=1;   //許容値を-1する
    }
    if(keyCode==RIGHT){//右キーを押した場合
      tolerance+=1;    //許容値を+1する
    }
  }
}

◇実行結果
Pc139

 
 
 赤いコーンをうまく認識しています。
 当初の要件は満たしていますが・・・・コーンを二個置くとこんな感じに・・・

 

Pc140

 今のプログラムでは、ターゲット以外に同色の物体が画面に入ると、位置がわからなくなってしまいますので今後の課題とします。

|

« 【Processing】 GSVideoでWebカメラを使う | トップページ | 【Processing】二値化した画像のラべリング »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: 【Processing】色識別:

« 【Processing】 GSVideoでWebカメラを使う | トップページ | 【Processing】二値化した画像のラべリング »