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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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.