import gohai.glvideo.*; //カメラを使うのに必要 //<>//
import gab.opencv.*; //画像処理に必要
import java.awt.Rectangle; 

GLCapture video;  //カメラ変数
OpenCV opencv; //画像処理に必要な変数
Rectangle[] faces; //認識された顔を格納する変数

//顔認識をするかどうか
//boolean useFaceDetect = true;
boolean useFaceDetect = false;

//顔認識した画像をモザイク処理するかどうか
boolean isMosaic = true;
//boolean isMosaic = false;

void setup()
{
  //1920x1080
  //int imWidth = 1920; int imHeight = 1080;
  //1280x720
  //int imWidth = 1280; int imHeight = 720;
  //640x480
  int imWidth = 640; int imHeight = 480;

  //窓のサイズを指定
  size(640, 480, P2D);

  //カメラを使用する準備 ここから
  String devices[] = GLCapture.list();
  printArray(devices);
  video = new GLCapture(this, devices[0], imWidth, imHeight);
  video.play(); 
  //カメラを使用する準備 ここまで

  //画像処理用変数を初期化
  opencv = new OpenCV(this, 640, 480);

  //画像処理する画像をカラーにする指定
  //この命令を実行しないとグレーになる
  opencv.useColor();

  //顔認識のデータベースを読み込み
  opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE);
}

void draw()
{  
  //カメラが有効かどうか
  if (video.available())
  {
    //cameraの画像を読み込み
    video.read();
    //取得した画像を画像処理用にセット
    PImage img =  video.copy();
    img.resize(640, 480);
    opencv.loadImage(img);

    //=====================================
    //image processing functions
    //=====================================
    //opencv.brightness(100);//0~255
    //opencv.contrast(2);//0.0~5?
    //opencv.threshold(100);//0-255
    //opencv.blur(5);
    //opencv.flip(1);//-1(H),0(V),1(H&V);
    //opencv.erode();
    //opencv.erode();opencv.erode();opencv.erode();opencv.erode();opencv.erode();opencv.erode();opencv.erode();
    //opencv.dilate();
    //opencv.dilate();opencv.dilate();opencv.dilate();opencv.dilate();opencv.dilate();opencv.dilate();opencv.dilate();opencv.dilate();

    //for only gray images
    //opencv.findSobelEdges(1,0);
    //opencv.findCannyEdges(30,50);//lowandhigh0~255
    //opencv.equalizeHistogram();
    
    //画像処理した結果を出力
    image(opencv.getOutput(), 0, 0);
    
    //ネガポジ反転
    //filter(INVERT);
    //ポスタリゼーション
    //filter(POSTERIZE, 4);

    //顔認識
    if (useFaceDetect)
    {
      //顔認識する
      faces = opencv.detect();

      if (isMosaic) 
      {
        noStroke();
        //顔が認識された範囲をモザイクする処理
        for (int i = 0; i < faces.length; i++) 
        {
          mosaicRect(faces[i]);
        }
      } else
      {
        //顔を囲う線の設定
        noFill();
        stroke(0, 255, 0);
        strokeWeight(3);

        //顔が認識された範囲を矩形で囲う処理
        for (int i = 0; i < faces.length; i++) 
        {
          rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height);
        }
      }
    }
  }
}

void mosaicRect(Rectangle rect)
{
  int mosaicWidth = 15;
  int mosaicHeight = 15;
  loadPixels();
  for (int j = rect.y; j < rect.y + rect.height; j+=mosaicHeight) 
  {
    for (int i = rect.x; i < rect.x + rect.width; i+=mosaicWidth)
    {
      color c = pixels[j * width + i];
      fill(c);
      rect(i, j, mosaicWidth, mosaicHeight);
    }
  }
}