7
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

OpenCVで顔認識・切り出し

Last updated at Posted at 2020-11-08

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

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

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フォルダに格納します。

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

###顔識別器設置
顔の識別器はこちらで公開されています。

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

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

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 aaa_79_106.png aaa_76_206.png aaa_527_257.png aaa_446_348.png aaa_438_41.png
aaa_385_140.png aaa_269_171.png aaa_254_330.png aaa_190_175.png aaa_152_22.png aaa_11_70.png

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

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

7
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?