Mac×OpenCV×Javaで環境構築をして顔認識してみた。


# はじめに
ネットを見ているとOpenCVの構築はC、PythonやAndroid/iOSのセットアップ記事が多いです。
というのも計算系のライブラリが豊富だったり、モバイルのニーズが高いというのが理由なのかな？と思ってます。


過去の大学時代にJavaを利用して深層学習や機械学習
をちょっとだけ勉強していて、
数年ぶりにまたOpenCVで遊んでみたいな〜と思ったのが理由になります。

今回はOpenCVの環境構築だけなので一旦顔認識まで出来るようにします。
備忘録がてらにメモしているので説明が悪いのはごめんなさい。

# 作業手順一覧
**1. JDKインストール**
**2. OpenCVインストール**
**3. InteliJインストール**
**4. OpenCV動作確認**
**5. 顔認識**


## JDKインストール方法
OracleのJDK19を利用します。
古いJDKを利用するとビルド時にOpenCVのコード部分でエラーが発生します。

https://zenn.dev/taktaky/articles/3e974dc7762953

インストールは下記コマンド

```brew install --cask oracle-jdk```


## OpenCVインストール手順

下記リンクに記載してある方法でインストールしていきます。

https://autolab-minoya.hatenablog.com/entry/2017/11/04/224627

**上記リンクの中にある４つの手順を抜き出しました。少し古い部分もあったので修正を加えています。**

1. ```brew install ant```でantをインストール。
これがないと目当ての.jarファイルが生成されないらしい…

2. 次に```brew edit opencv```を実行し，```-DBUILD_opencv_java=OFFであればONに書き換える．```
(2022.11月現在 標準でOFFになっていました)
因みにこの部分をONにしないと--with-javaオプションが働かないです。
自分は最初これを知らずにjarファイルが出来なくてがっつり躓きました…

3. ```brew install --build-from-source opencv```を実行してOpenCVをインストール。
インストールにとても時間かかるので，時間に余裕のあるときにやると良いです。

4. 3で，エラーを吐かずにインストールが完了していれば，
```/usr/local/Cellar/opencv/4.6.0_1/share/OpenCV/java```に```opencv_java460.jar```ができているはずです．
javaというフォルダがなければjarファイルのインストールに失敗しています。



## InteliJインストールとOpenCVのjarファイル設定
下記IntelliJのリンク　Communityの方をダウンロード

https://www.jetbrains.com/ja-jp/idea/download/#section=mac

**1.「NewProject」押下**
**2.任意のプロジェクト名を決める**
**3.先ほどインストールしたOracleJDKを追加する**
**4.Createボタンを押下**
**5.「File」->「Project Structure」を選択**
**6.「Project Settings」->「Modules」を選択**
**7.「Module SDK」が先ほどインストールしたJDKであること**
**8.「＋」ボタンを押下し、「JARs or Directories...」を押下**
**9.「/usr/local/Cellar/opencv/4.6.0_1/share/OpenCV/java/opencv4/opencv_java460.jar」を選択する**
**10.追加したライブラリをダブルクリックし、「Configure Module Library」から「＋」を押下し、「/usr/local/Cellar/opencv/4.6.0_1/share/OpenCV/java/opencv4/libopencv_java460.dylib」を追加して「OK」ボタン押下**
**11.Sampleのソースコードを読み込ませて動作確認する**


**1.「NewProject」押下**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487318/105304c5-411c-a242-2011-015404bd4526.png" width="100%">


**2.任意のプロジェクト名を決める**
**3.先ほどインストールしたOracleJDKを追加**
**4.Createボタン押下**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487318/d442f0ff-1ca0-ffb0-5948-0900f8725941.png" width="100%">


**5.「File」->「Project Structure」を選択**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487318/86ea26c5-798a-15a9-4046-236286a6d213.png" width="100%">


**6.「Project Settings」->「Modules」を選択**
**7.「Module SDK」が先ほどインストールしたJDKであること**
**8.「＋」ボタンを押下し、「JARs or Directories...」を押下**
**9.「/usr/local/Cellar/opencv/4.6.0_1/share/OpenCV/java/opencv4/opencv_java460.jar」を選択する**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487318/53c51e66-f3f2-15c3-afdc-db47d71beda8.png" width="100%">

**10.追加したライブラリをダブルクリック
「Configure Module Library」から「＋」を押下「/usr/local/Cellar/opencv/4.6.0_1/share/OpenCV/java/opencv4/libopencv_java460.dylib」を追加
「OK」ボタン押下**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487318/13ffe481-28e4-5ba4-4d8b-93fd4fdf8acf.png" width="100%">

**11.Sampleのソースコードを読み込ませて動作確認する**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487318/8a49b276-e724-ac68-ffda-5f1b725890af.png" width="100%">

**Sampleのソースコード**

```
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
public class Main {
    public static void main(String[] args) {
        System.out.println("Welcome to OpenCV " + Core.VERSION);
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat m  = Mat.eye(3, 3, CvType.CV_8UC1);
        System.out.println("m = " + m.dump());
    }
}
```


以上でOpenCVの設定は完了です。



# 顔認識
特徴量ファイルがインストールしたOpenCVフォルダにあるので顔認識をしていく。
本当は自分で特徴量を作成したいですが、今回はこはスキップします。

手順は以下３点です
**1. ![スクリーンショット 2022-11-10 16.33.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487318/29408788-d639-4148-5c7f-d9e4f5bde17a.png)
 Lennaの画像をプロジェクト直下に入れる**
**2. haarcascade_frontalface_alt_tree.xmlをプロジェクト直下に入れる**
**3. 顔検出用のソースコードを記載**

### Lennaの画像
画像処理といったらレナの画像ですね。
今回はこの画像を使います。 
input.pngと名前をつけてプロジェクトフォルダ直下に保存してください。
![Lenna.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487318/80818b13-8ce1-1692-4486-8b669f5301a9.png)


### カスケード分類
haarcascadesディレクトリにある```haarcascade_frontalface_alt_tree.xml```を使用します。

ダウンロードしたOpenCVの中にある特徴量を使う。
下記の場所にあると思います。
```
/usr/local/Cellar/opencv/4.6.0_1/share/opencv4/haarcascades/haarcascade_frontalface_alt_tree.xml
```
プロジェクト直下にいれちゃってください。


**余談ですが・・・・**
haarcascadesディレクトリには他にも数種類の特徴量ファイルがあるので、
気になったものがあれば利用してみてください。下記に特徴量一覧の情報があります。

https://qiita.com/hitomatagi/items/04b1b26c1bc2e8081427





### 顔検出するソースコード
```
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;

public class Main {
    public static void main(String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        // 入力画像の取得
        Mat im = Imgcodecs.imread("input.png");
        // カスケード分類器で顔探索
        CascadeClassifier faceDetector = new CascadeClassifier("haarcascade_frontalface_alt_tree.xml");
        MatOfRect faceDetections = new MatOfRect();
        faceDetector.detectMultiScale(im, faceDetections);
        // 見つかった顔を矩形で囲む
        for (Rect rect : faceDetections.toArray()) {
            Imgproc.rectangle(im, new Point(rect.x, rect.y),
                    new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 0, 255), 5);
        }
        // 結果を保存
        Imgcodecs.imwrite("ouput.png", im);
    }
}
```

### 手順1,2,3までを行なったらこんな感じになります。ここでビルドするとoutput.pngが追加されます。
![スクリーンショット 2022-11-10 16.33.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487318/89d0760b-d394-9dd2-61d5-5d04d6538a54.png)

### 顔検出結果
![スクリーンショット 2022-11-10 16.34.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487318/a19e82c2-2e12-0447-0f10-b749f8d07821.png)


顔部分が赤色の枠で覆われています。顔認識がされてますね。
お疲れ様でした。


次回は特徴量ファイル作成について投稿できればと思ってます。
ありがとうございました。