30行で顔認識(OpenCV)してファイル出力！

# やること
- [前回記事](https://qiita.com/hiraku00/items/1f71fa2bab8e0f58cdcf)でGoogle画像検索結果をスクレイピングし、画像データをダウンロードしました。
- 今回は、人物の画像データをダウンロードしておき、その人物の顔部分をOpenCVで認識させ、顔画像のデータを作成したいと思います。

# 手順概要
1. cascadeファイルの準備
2. 画像データの準備
3. 顔認識 & ファイル出力

# 動作環境
- macOS Catalina 10.15 beta
- anaconda 4.6.14
- Python 3.6.8
- opencv 3.4.2

# 1. cascadeファイルの準備
- 私の場合はanacondaで環境構築をしているため、"anaconda3/pkgs/.../haarcascades/"の中に「haarcascade_frontalface_default.xml」があります。(Finderなどで検索してみてください)  
それをコピーして、実行ファイルと同じディレクトリに格納しました。
- ファイルが無い場合は、[GitHub](https://github.com/opencv/opencv/tree/master/data/haarcascades)上からダウンロードしてください。

```python:1.cascadeファイルの準備
import os
import cv2

HAAR_FILE = "./haarcascade_frontalface_default.xml"
face_cascade = cv2.CascadeClassifier(HAAR_FILE)
```

# 2. 画像データの準備
- 入力元ファイルと出力先ファイルを格納するフォルダ(input/output)を作成しておき、入力元には複数の画像データ(.jpg)を格納しておきます。

```python:2.画像データの準備
IN_PATH = './input/'
OUT_PATH = './output/'

def get_file(dir_path):
    file_names = os.listdir(dir_path)
    return file_names

images = get_file(IN_PATH)
```

# 3. 顔認識 & ファイル出力
- 画像データを読み込みます(imread)
- 画像を検出しやすいようにグレースケールに変換します(cvtColor)
- 顔認識を実行するため、1.で読み込みしたcascadeを利用します  
  detectMultiScaleの戻り値は、下記のリストになります
  - x座標
  - y座標
  - 横幅
  - 縦幅
- 顔の範囲を抽出、または範囲を赤枠(OpenCVのimreadはBGRの順)で囲み、それぞれのファイルを出力します
- rectangleは四角形を描画します。
  - rectangle(画像, 左上座標, 右下座標, 色, 線の太さ)

```python:3.顔認識&ファイル出力
for i in images:

    # read image
    img = cv2.imread(IN_PATH + i)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # face detection
    face = face_cascade.detectMultiScale(gray)

    # get face area
    for x,y,w,h in face:
        face_cut = img[y:y+h, x:x+w]
    # wrap in red frame
    for x,y,w,h in face:
        cv2.rectangle(img, (x,y), (x+w, y+h), (0, 0, 255), 2)

    cv2.imwrite(OUT_PATH + '{}_face_cut.jpg'.format(i.replace('.jpg', '')), face_cut)
    cv2.imwrite(OUT_PATH + '{}_face_rectangle.jpg'.format(i.replace('.jpg', '')), img)
```

# 実行結果
- 実行前後の画像データは以下の通りです。

### 【実行前】  
#### 1. 001.jpg
![001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67194/8a47f7f5-481b-435c-f64a-ed6f19ccacd8.jpeg)

#### 2. 002.jpg
![002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67194/d482f683-7d37-52d7-c202-044b16dabc2d.jpeg)

#### 3. 003.jpg
![003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67194/7308e02a-d730-21ab-4a9c-774d79c5026f.jpeg)


### 【実行後】
#### 1.
#### 001_face_cut.jpg
![001_face_cut.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67194/11ab9bf7-4e1d-a463-b0bd-f5200caf988a.jpeg)
#### 001_face_rectangle.jpg
![001_face_rectangle.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67194/376dbac8-8291-0d50-a155-f95581093072.jpeg)

#### 2.
#### 002_face_cut.jpg
![002_face_cut.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67194/987241a7-8446-bbc9-5f28-3c1526172e13.jpeg)
#### 002_face_rectangle.jpg
![002_face_rectangle.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67194/f5656d45-e97c-ce88-559c-2ec329454d8b.jpeg)

#### 3.
#### 003_face_cut.jpg
![003_face_cut.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67194/94ad96c0-f37a-3c99-43b1-e15cfb9c9054.jpeg)
#### 003_face_rectangle.jpg
![003_face_rectangle.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67194/f541162a-0b03-c96c-f287-5704f97c08f8.jpeg)

# ソースコード
https://github.com/hiraku00/face-detection

# 参考文献
- [OpenCVで顔認証を行いトリミングして保存する](https://newtechnologylifestyle.net/opencv_face_trimingu/)