4
5

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 1 year has passed since last update.

大量の写真から顔を切り抜いてデータセットをつくりたい--OpenCVで自動処理

Last updated at Posted at 2022-01-24

#OpenCVで顔を切り抜く手法です

#機械学習のデータセットを作りたい
コンピュータビジョンのタスクには、人間の顔を含む画像をデータセットとするものがたくさんあります。
そのようなデータセットを作るために、大量の画像から顔を検出して切り抜きたい時があります。

#dlibの顔検出が使える
pythonを使えば、特別な設定なしで顔を切り抜けます。

#コード

今回はこちらの画像を切り抜きます。

顔検出機をインポートします。

import dlib

faceDetector = dlib.get_frontal_face_detector()

顔検出機で画像内の顔の四角形座標を取ります。

img = cv2.imread(img_path)
faces = faceDetector(img, 0)

検出した顔ごとに、元画像から切り抜きます。

if len(faces) > 0:
    for i in range(0, len(faces)):      
      face_img = img[int(faces[i].top()):int(faces[i].bottom()),int(faces[i].left()):int(faces[i].right())]

もう少し広めに切り抜きたい場合は、顔の四角形にパディングを加えます。

rect_top = int(faces[i].top()) - (face_h * padding)
if rect_top < 0:
   rect_top = 0
rect_bottom = int(faces[i].bottom()) + (face_h * padding)
if rect_bottom > img_h:
   rect_bottom = img_h
rect_left = int(faces[i].left()) - (face_w * padding)
if rect_left < 0:
   rect_left = 0
rect_right = int(faces[i].right()) + (face_w * padding)
if rect_right > img_w:
   rect_right = img_w

face_img = img[int(rect_top):int(rect_bottom),int(rect_left):int(rect_right)]

顔の四角形*1のパディングを四方に取ると、だいたいバストアップの画像が取れました。

コード全体。

import dlib
import cv2

def crop_face(path, write_path, padding):

   faceDetector = dlib.get_frontal_face_detector()
   img = cv2.imread(path)
   faces = faceDetector(img, 0)
  
   if len(faces) > 0:
      for i in range(0, len(faces)):
         img_h, img_w, c = img.shape
         face_h = int(faces[i].bottom() - faces[i].top())
         face_w = int(faces[i].right() - faces[i].left())

         rect_top = int(faces[i].top()) - (face_h * padding)
         if rect_top < 0:
            rect_top = 0
         rect_bottom = int(faces[i].bottom()) + (face_h * padding)
         if rect_bottom > img_h:
            rect_bottom = img_h
         rect_left = int(faces[i].left()) - (face_w * padding)
         if rect_left < 0:
            rect_left = 0
         rect_right = int(faces[i].right()) + (face_w * padding)
         if rect_right > img_w:
            rect_right = img_w

         face_img = img[int(rect_top):int(rect_bottom),int(rect_left):int(rect_right)]
         cv2.imwrite(write_path, face_img)

#自動処理で大量のデータを切り抜けます

上記コードで元データをループ処理すれば、自動で大量の画像を切り抜くことができます。

🐣


フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習/AR関連の情報を発信しています。

Twitter
Medium

4
5
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
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?