OpenCVで顔認識・切り出し

###はじめに
画像中の顔を認識させて四角の枠で囲むコードを改造して、ファイルとして切り出すコードを作成してみました。

###ライブラリーのインポート
OpenCV、Pillow等のライブラリーをインポートします。

```python
import os
import subprocess
from PIL import Image
import cv2 as cv

dir0 = 'org' 
dir1 = 'png'
dir2 = 'png_resize'
dir3 = 'face'
```

###画像準備
元画像（jpg,大きさ500×334px）をorgフォルダに置きます。これをpngファイルに変換し、サイズ幅を600pxに調整した後、png_resizeフォルダに格納します。

```python
files0 = os.listdir(dir0)
files0.sort()

for file in files0:

    if '.jpg'  in file:        
        command = 'sips --setProperty format png ' + dir0 +'/' + file +  ' --out ' + dir1 +'/' +  file.replace('.jpg','.png') 
        subprocess.call(command, shell=True)
        print(file) 

files1 = os.listdir(dir1)
files1.sort()

# aaa.jpg  

for file in files1:   
    if '.png' in file:   
        img0 = os.path.join(dir1, file)
        img0_img = Image.open(img0)
        h = img0_img.height
        w = img0_img.width
        img1_img = img0_img.resize((600,round(600*h/w)))
        img1 = os.path.join(dir2, file) 
        img1_img.save(img1)
        print(file) 

# aaa.png

files2 = os.listdir(dir2)
files2.sort()    
```

![aaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311614/3de4ae94-ea02-127b-ad21-aa14fd2901cf.png)

###顔識別器設置
顔の識別器は[こちら](https://github.com/opencv/opencv/blob/master/data/haarcascades/ "こちら")で公開されています。

```python
face_cascade = cv.CascadeClassifier('haarcascade_frontalface_default.xml')
#face_cascade = cv.CascadeClassifier('haarcascade_profileface.xml')
```

###顔識別器実行、顔画像切り出し
顔画像の切り出しを実行します。切り出し範囲を検出範囲より上下左右10px広くしています。

```python
for file in files2:
    if '.png' in file:
        dirfile = os.path.join(dir2, file) 
        img = cv.imread(dirfile)
        gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
        
        faces = face_cascade.detectMultiScale(gray, 1.3, 5)
        
        for (x,y,w,h) in faces:
            face = img[y-10:y+h+10, x-10:x+w+10]
            face_name = str(file.strip('.png'))+'_'+str(x)+'_'+str(y)+'.png'
            dirface = os.path.join(dir3,face_name)
            facefile = cv.imwrite(dirface, face) 
            #cv.rectangle(img,(x-10,y-10),(x+w+10,y+h+10),(255,0,0),2)
            print(face_name)  

# aaa_152_22.png
# aaa_11_70.png
# aaa_438_41.png
# aaa_79_106.png
# aaa_385_140.png
# aaa_190_175.png
# aaa_269_171.png
# aaa_76_206.png
# aaa_527_257.png
# aaa_91_277.png
# aaa_254_330.png
# aaa_446_348.png  
```

上記画像から計12枚の顔画像が切り出されました。顔の大部分が写っていれば切り出しに成功していることが分かります。

![aaa_91_277.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311614/68a3983e-7657-4441-2f7b-cb3fb8a2eb9e.png) ![aaa_79_106.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311614/ab79a822-95d8-9cc1-9b47-a0fcbe5db8a2.png) ![aaa_76_206.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311614/684ca82c-6841-822e-60d5-bb0f2462fc9f.png) ![aaa_527_257.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311614/34989375-8a9b-ec78-f6c7-163fcc7f7d21.png) ![aaa_446_348.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311614/a5d0237e-dfc7-bb57-d7fa-20fc6baedbea.png) ![aaa_438_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311614/78c74418-4e6f-5df0-c646-22692cf1da0b.png) 
![aaa_385_140.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311614/f2a5bbb4-943e-4593-a719-13c9bc27a8b4.png) ![aaa_269_171.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311614/7a4e6bab-5a5f-40b0-7f10-71f05fd92fbb.png) ![aaa_254_330.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311614/8b13cae6-9c9e-69b4-ba2c-4b13f315f512.png) ![aaa_190_175.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311614/e13f048a-1972-30e1-e93d-aebf9e51615c.png) ![aaa_152_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311614/61bf3d91-6d12-6bed-43c9-7277f257ce7a.png) ![aaa_11_70.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311614/a9ffc018-8386-f03b-f7c9-480e36260389.png)

###終わりに
集合写真から写真付きで名簿を作る場合等で使えそうです。訓練された識別器がカスケードファイルとして公開されていると、誰でも利用できて便利ですね。

###参考
https://docs.opencv.org/4.1.0/d7/d8b/tutorial_py_face_detection.html
https://github.com/opencv/opencv/tree/master/data/haarcascades