4.5 ライブラリの利用(OpenCV for Processing)

      4.5 ライブラリの利用(OpenCV for Processing) はコメントを受け付けていません

ライブラリとは、Processingに機能を追加するもので、開発環境によっては機能拡張(Extension)、アドオン(add-on)などと呼ばれることもあります。

Processing公式サイトにライブラリのリストがあるので、興味があるライブラリがあったら、インストールして使ってみましょう。
https://processing.org/reference/libraries/

「4.4 画像処理」からの続きになりますが、この節では画像処理やコンピュータビジョンのライブラリである、OpenCV for Processingを利用してみます。

4.5.1 OpenCV for Processingのインストール

まずは、Processingのインタフェースからライブラリをインストールします。

Sketchメニュー > Import Library… > Add Library…を選択すると次の画面が表示されます。

2016_09_25_0_14
図4.5-a

OpenCVで検索し、「OpenCV for Processing」ライブラリを選択してインストールしましょう。

2016_09_25_0_15
図4.5-b

問題なくライブラリがインストールされたら、サンプルも同時にインストールされています。Fileメニュー > Examples…を選んでExampleのリストを表示しす。

2016_09_25_0_28
図4.5-c

Contributed Libraries > OpenCV for Processingの中に色々なサンプルがあります。

2016_09_25_0_31
図4.5-d

4.5.2 カメラ映像の表示

PCにカメラが付いていない場合にはwebカメラなどを使ってください。
まずは、カメラ映像を表示します【リスト4.5-a】。

2016_10_07_20_54
図4.5-e

次のサンプルを実行しましょう。

リスト4.5-a
import gab.opencv.*;  //ライブラリをインポート
import processing.video.*;
import java.awt.*;

Capture video;
OpenCV opencv;

void setup() {
  size(640, 480);
  //使用できるカメラのリスト
  String[] cameras = Capture.list();
  
  //カメラが認識されないようなら、以下のコードを追加
  while (cameras.length == 0) {
    cameras = Capture.list();
  }

  //カメラの番号をcameras[0]のようにインデックス番号で明示する
  video = new Capture(this, cameras[0]);
  opencv = new OpenCV(this, 640, 480);

  video.start();  //キャプチャを開始
}

void draw() {
  opencv.loadImage(video);  //ビデオ画像をメモリに展開
  image(video, 0, 0 );  //表示
}

void captureEvent(Capture c) {
  c.read();
}

4.5.3 明るさとコントラスト

明るさとコントラストのコントロールは次のサンプルになります。
明るさは、-225〜225の間で変化します。
また、コントラストは0.0から始まりますが、100.0以上はほとんど変化がありません。
次のサンプルではコントラストの調節部分がコメントアウトされているので、コントラストを確認したい場合はそちらを有効にしてください。

2016_10_07_21_24
図4.5-f
リスト4.5-b
import gab.opencv.*;  //ライブラリをインポート
import processing.video.*;
import java.awt.*;

Capture video;
OpenCV opencv;

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

  //使用できるカメラのリスト
  String[] cameras = Capture.list();
  
  //カメラが認識されないようなら、以下のコードを追加
  while (cameras.length == 0) {
    cameras = Capture.list();
  }

  //カメラがなかった場合
  if (cameras.length == 0) {
    
    println("no camera");
    exit();  //終了
    
  } else {
    
    //カメラがあった場合は、リストを出力
    println("Cameras are");
    for (int i = 0; i < cameras.length; i++) println(cameras[i]);

    //カメラの番号をcameras[0]のようにインデックス番号で明示する
    video = new Capture(this, cameras[0]);
    opencv = new OpenCV(this, 640, 480);

    video.start();  //キャプチャを開始
  }
}

void draw() {
  opencv.loadImage(video);  //ビデオ画像をメモリに展開

  //明るさの調節。-255〜255。
  opencv.brightness(int(map(mouseX, 0, width, -255, 255)));

  //コントラストの調節。0.0から始まるが
  //100以上になるとほとんど変わらない。
  //opencv.contrast(map(mouseX, 0, width, 0.0, 5.0));

  image(opencv.getOutput(), 0, 0 );  //表示
}

void captureEvent(Capture c) {
  c.read();
}

4.5.4 エッジの検出

コンピュータビジョンではよく見るタイプのエフェクトです。モノクロでのみ再生可能です。サンプルではCannyフィルタ、Scharrフィルタ、Sobelフィルタを再生できるようになっています。

2016_10_07_21_25
図4.5-g
リスト4.5-c
import gab.opencv.*;  //ライブラリをインポート
import processing.video.*;
import java.awt.*;

Capture video;
OpenCV opencv;
PImage canny, scharr, sobel;

void setup() {
  size(640, 480);
  //使用できるカメラのリスト
  String[] cameras = Capture.list();
  
  //カメラが認識されないようなら、以下のコードを追加
  while (cameras.length == 0) {
    cameras = Capture.list();
  }

  //カメラがなかった場合
  if (cameras.length == 0) {
    
    println("no camera");
    exit();  //終了
    
  } else {
    
    //カメラがあった場合は、リストを出力
    println("Cameras are");
    for (int i = 0; i < cameras.length; i++) println(cameras[i]);

    //カメラの番号をcameras[0]のようにインデックス番号で明示する
    video = new Capture(this, cameras[0]);
    opencv = new OpenCV(this, 640, 480);

    video.start();  //キャプチャを開始
  }
}

void draw() {
  opencv.loadImage(video);  //ビデオ画像をメモリに展開

  //canny(キャニー)フィルターを使用
  //findCannyEdges(int low, int hgih)
  //high以上のエッジ強度はエッジにする。low以下はエッジにしない

  opencv.findCannyEdges(50, 200);
  canny = opencv.getSnapshot();
  image(canny, 0, 0 );  //表示
  
  //Scharrフィルターを使用
  /*
  opencv.findScharrEdges(OpenCV.HORIZONTAL);
  scharr = opencv.getSnapshot();
  image(scharr, 0, 0 );  //表示
  */
  
  //sobel(ソーベル)フィルターを使用
  //findSobelEdges(int dx, int dy)は、x, y方向へのずれ。
  //それぞれ0~2の値をとるが、(0, 0)だとエラーになる。
  /*
  opencv.findSobelEdges(1, 0);
  sobel = opencv.getSnapshot();
  image(sobel, 0, 0 );  //表示
  */
}

void captureEvent(Capture c) {
  c.read();
}

4.5.5 二値化、ぼかし

白黒2色にする場合と、ぼかす場合です。

2016_10_07_21_26
図4.5-h
リスト4.5-d
import gab.opencv.*;  //ライブラリをインポート
import processing.video.*;
import java.awt.*;

Capture video;
OpenCV opencv;
PImage  img, thresh, blur, adaptive;

void setup() {
  size(640, 480);
  //使用できるカメラのリスト
  String[] cameras = Capture.list();
  
  //カメラが認識されないようなら、以下のコードを追加
  while (cameras.length == 0) {
    cameras = Capture.list();
  }

  //カメラがなかった場合
  if (cameras.length == 0) {
    
    println("no camera");
    exit();  //終了
    
  } else {
    
    //カメラがあった場合は、リストを出力
    println("Cameras are");
    for (int i = 0; i < cameras.length; i++) println(cameras[i]);

    //カメラの番号をcameras[0]のようにインデックス番号で明示する
    video = new Capture(this, cameras[0]);
    opencv = new OpenCV(this, 640, 480);

    video.start();  //キャプチャを開始
  }
}

void draw() {
  opencv.loadImage(video);  //ビデオ画像をメモリに展開

  //二値化。0〜255の間で、白黒に分割。
  opencv.threshold(50);
  thresh = opencv.getSnapshot();
  image(thresh, 0, 0 );  //表示
  
  //ぼかし。値を増やすとボケ具合が強くなる。
  /*
  opencv.blur(12);  
  blur = opencv.getSnapshot();
  image(blur, 0, 0 );  //表示
  */
}

void captureEvent(Capture c) {
  c.read();
}

4.5.6 顔の検出

顔を検出するプログラムです。このほか、顔の検出以外にも目、耳、鼻、口なども検出できます。

2016_10_07_21_27
図4.5-i

使用できる関数が以下のサイトに記載されています。
http://atduskgreg.github.io/opencv-processing/reference/gab/opencv/OpenCV.html

リスト4.5-e
import gab.opencv.*;
import processing.video.*;
import java.awt.*;

Capture video;
OpenCV opencv;

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

  //使用できるカメラのリスト
  String[] cameras = Capture.list();
  
  //カメラが認識されないようなら、以下のコードを追加
  while (cameras.length == 0) {
    cameras = Capture.list();
  }

  //カメラがなかった場合
  if (cameras.length == 0) {

    println("no camera");
    exit();  //終了
  } else {

    //カメラがあった場合は、リストを出力
    println("Cameras are");
    for (int i = 0; i < cameras.length; i++) println(cameras[i]);

    //キャプチャは320x240にする
    video = new Capture(this, width/2, height/2, cameras[0]);  
    opencv = new OpenCV(this, width/2, height/2);

    //顔用のデータをロード  
    opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE);
    //目のデータをロード
    //opencv.loadCascade(OpenCV.CASCADE_EYE);  
    //口のデータをロード
    //opencv.loadCascade(OpenCV.CASCADE_MOUTH);

    video.start();  //キャプチャを開始
  }
}

void draw() {
  scale(2);  //画像を2倍に拡大
  opencv.loadImage(video);  //ビデオ画像をメモリに展開
  image(video, 0, 0 );  //表示

  //顔の領域を検出
  noFill();
  stroke(0, 255, 0);
  strokeWeight(3);
  Rectangle[] faces = opencv.detect();
  println(faces.length);

  //顔が複数あった場合には、全て検出
  for (int i = 0; i < faces.length; i++) {
    println(faces[i].x + "," + faces[i].y);
    rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height);
  }
}

void captureEvent(Capture c) {
  c.read();
}