OpenCV

さて、次はオープンソースの画像処理ライブラリである、OpenCVを使ってみます。
元のOpenCVはC++用に書かれていて、ここで使うものはProcessing用に機能を限定したものです。
ですが、それでも使いようによっては便利な機能があるので、ある程度の細かい画像処理ができます。

インストール

まずは、OpenCVをインストールします。以下のページを開いてください。ここには、processingで使える機能も全て出ています。
http://ubaa.net/shared/processing/opencv/

このページの上の方にある、opencv-framework-1.1.dmgをダウンロードし、インストールします。
ミラーサーバ
 

次に、OpenCV Processing Libraryをダウンロードし、ProcessingのLibrariesフォルダに入れましょう(下図を参照して下さい。)

opecv_directory

サンプルが欲しい人は以下のリンクからダウンロードしてください。
OpenCV processing examples

そして、Processingを再起動しましょう。

最初のプログラム

まずは、簡単なサンプルをやってみましょう。
一定のしきい値によって白黒に表示するプログラムです。

threshold

import hypermedia.video.*;    //ライブラリを使う
OpenCV opencv;    //OpenCV型の変数を宣言

void setup() {
  size( 640, 480 );

  // open video stream
  opencv = new OpenCV( this );
  opencv.capture( 640, 480 );    //キャプチャを行う
}

void draw() {

  opencv.read();    //カメラから映像を取り込む
  opencv.convert(OpenCV.GRAY);    //グレーに変更する
  opencv.threshold(80);    //80から255までの間を白にする

  image( opencv.image(), 0, 0 );  //映像を表示する。0, 0は映像の左上座標
}

どうでしょうか?既に行った実習でも似たようなことをしましたが、それよりもかなり簡単にできたと感じたのではないでしょうか?

flip

次は、映像の反転です。これも先週やりましたよね?今度はもっと簡単です。

flip

import hypermedia.video.*;    //ライブラリを使う
OpenCV opencv;    //OpenCV型の変数を宣言

void setup() {
    size( 640, 240 );

    opencv = new OpenCV(this);
    opencv.capture( 320, 240 );    //キャプチャを行う
}

void draw() {

    opencv.read();
    opencv.flip( OpenCV.FLIP_BOTH ); //上下左右を反転させる

    //ビデオの表示
    image( opencv.image(OpenCV.SOURCE), 0, 0 );    //元映像
    image( opencv.image(), 320, 0 );    //反転された映像
}

上記では、opencv.flip( OpenCV.FLIP_BOTH );となっていて、上下左右を反転させる設定になっています。3つのモードがあります。FLIP_HORIZONTAL(左右反転)、FLIP_VERTICAL(上下反転)、 FLIP_BOTH(上下左右反転)の3種類があります。

フレーム差分

フレーム差分も先ほどやりましたが、このコードもかなり短くなってます。

absdiff

import hypermedia.video.*;    //ライブラリを使う
OpenCV opencv;    //OpenCV型の変数を宣言

void setup() {
  size( 640, 480 );

  opencv = new OpenCV(this);
  opencv.capture( 320, 240 );    //キャプチャを行う
}

void draw() {
  opencv.read();    //カメラから映像を取り込む
  image( opencv.image(), 0, 0);    //元映像
  opencv.absDiff();    //現在の映像と保存された画像を比較する

  image( opencv.image(OpenCV.MEMORY), 320, 0 );  //保存された画像を右上に表示
  image( opencv.image(), 320, 240 );             //結果を右下に表示
}

void keyPressed() {
  opencv.remember();  //画像を保存する
}

物体の認識(トラッキング)

さて、一番難しいトラッキングです。
サンプルを用意してみたので、参考にしてみましょう。詳細は授業中に触れます。

blob

import java.awt.Rectangle;
import java.awt.Point;

import hypermedia.video.*;
OpenCV opencv;

int w = 320;
int h = 240;
int threshold = 80;
boolean find=true;
PFont font;

void setup() {
  size( w*2, h);

  opencv = new OpenCV( this );    //OpenCVを使うことを宣言する
  opencv.capture(w,h);    //w x hのサイズのキャプチャ映像を取り込む(この場合、320 x 240)

  font = createFont("Monaco", 9); 
  textFont(font);

  println( "Drag mouse inside sketch window to change threshold" );
  println( "Press space bar to record background image" );
}


void draw() {

  background(0);
  opencv.read();
  //image( opencv.image(), 0, 0);    //元映像

  opencv.absDiff();
  opencv.threshold(threshold);
  image( opencv.image(), 0, 0); // 背景画像とキャプチャ映像の差

  // blobの作成
  //blobs(最小ピクセル、最大ピクセル、blobの最大数、穴の空いたblobがあるか)
  Blob[] blobs = opencv.blobs( 100, w*h/3, 20, true );

  noFill();
  translate(320, 0);
  //blobの数を数える
  for( int i = 0; i < blobs.length; i ++ ) {

    Rectangle bounding_rect = blobs[i].rectangle;    //blobを囲った四角形
    float area = blobs[i].area;    //面積
    float circumference = blobs[i].length;    //外周
    Point centroid = blobs[i].centroid;    //blobの中心点
    Point[] points = blobs[i].points;    //blobの構成点

    //四角形
    noFill();
    //blobが穴であるかどうかを判断し、穴だったら白、そうでなかったら暗いグレーの四角形を作成
    if(blobs[i].isHole == true) stroke(255);
    else stroke(64);
    
    //blobの周辺の四角を描画
    rect( bounding_rect.x, bounding_rect.y, bounding_rect.width, bounding_rect.height );

    //blobの中心を描画
    stroke(0,0,255);
    line( centroid.x-5, centroid.y, centroid.x+5, centroid.y );    //中心から水平線を描画
    line( centroid.x, centroid.y-5, centroid.x, centroid.y+5 );    //中心から垂直線を描画
    noStroke();
    fill(0,0,255);
    text( area,centroid.x+5, centroid.y+5 );    //面積を表示

    //オブジェクトの境界を描画し、その中を塗りつぶす
    fill(255,0,255,64);
    stroke(255,0,255);
    if ( points.length>0 ) {
      beginShape();
      for( int j = 0; j < points.length; j ++ ) {
        vertex( points[j].x, points[j].y );
      }
      endShape(CLOSE);
    }

    //オブジェクトの外周を表示
    noStroke();
    fill(255,0,255);
    text( circumference, centroid.x+5, centroid.y+15 );

  }
}

//スペースキーが押された時に画像を記憶する。
void mousePressed() {
  opencv.remember();
}

public void stop() {
  opencv.stop();
  super.stop();
}

//注意!!!!!
//Processingのバージョンが1.1の場合は、下記の2行を冒頭に追加する。
//import java.awt.Rectangle;  
//import java.awt.Point;

1 thought on “OpenCV

  1. Pingback: OpenCVことはじめ : circumstance evidence

Comments are closed.