さて、次はオープンソースの画像処理ライブラリである、OpenCVを使ってみます。
元のOpenCVはC++用に書かれていて、ここで使うものはProcessing用に機能を限定したものです。
ですが、それでも使いようによっては便利な機能があるので、ある程度の細かい画像処理ができます。
インストール
まずは、OpenCVをインストールします。以下のページを開いてください。ここには、processingで使える機能も全て出ています。
http://ubaa.net/shared/processing/opencv/
このページの上の方にある、opencv-framework-1.1.dmgをダウンロードし、インストールします。
ミラーサーバ
次に、OpenCV Processing Libraryをダウンロードし、ProcessingのLibrariesフォルダに入れましょう(下図を参照して下さい。)
サンプルが欲しい人は以下のリンクからダウンロードしてください。
OpenCV processing examples
そして、Processingを再起動しましょう。
最初のプログラム
まずは、簡単なサンプルをやってみましょう。
一定のしきい値によって白黒に表示するプログラムです。
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
次は、映像の反転です。これも先週やりましたよね?今度はもっと簡単です。
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種類があります。
フレーム差分
フレーム差分も先ほどやりましたが、このコードもかなり短くなってます。
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(); //画像を保存する
}
物体の認識(トラッキング)
さて、一番難しいトラッキングです。
サンプルを用意してみたので、参考にしてみましょう。詳細は授業中に触れます。

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;





Pingback: OpenCVことはじめ : circumstance evidence