LoginSignup
0
2

More than 3 years have passed since last update.

夏休みなので小学生とPythonを勉強してみた - 課題9 顔の検出

Last updated at Posted at 2019-08-23

小学6年生の長男が夏休みの自由研究にPythonを勉強したいというので付き合ってみました。
どこから手を付けていけばわからないので、いくつか課題を出し、それを実現するコードを一緒に書くということを繰り返しました。

この記事では、「課題9 顔の検出」について扱います。その他の課題については下記の記事をご覧ください。

コードはGitHubにて公開しています。

課題9-1 画像一覧

指示

./srcにある画像の一覧を表示しましょう。

回答例

import glob
import os

for image_path in glob.glob('./src/*.jpg'):
    image_name = os.path.basename(image_path)
    print(f'image_path: {image_path} image_name: {image_name}')

実行例

image_path: ./src/DSCN0295.jpg image_name: DSCN0295.jpg
image_path: ./src/DSCN0320.jpg image_name: DSCN0320.jpg
image_path: ./src/DSCN0347.jpg image_name: DSCN0347.jpg
image_path: ./src/DSCN0351.jpg image_name: DSCN0351.jpg
image_path: ./src/DSC_6152.jpg image_name: DSC_6152.jpg
image_path: ./src/DSC_6322.jpg image_name: DSC_6322.jpg
image_path: ./src/DSC_6509.jpg image_name: DSC_6509.jpg
以下略

課題9-2 顔の検出

指示

./srcにある画像から、顔の検出を行うプログラムを作りましょう。

ヒント

OpenCVには事前に学習を済ませた顔検出のための識別器があります。

回答例

今回はhaarcascade_frontalface_alt.xmlを使用します。まずcv2.CascadeClassifierで識別器を読み込みます。次にcv2.imreadで画像を読み込み、cv2.cvtColorでグレーに変換し、detectMultiScaleで顔検出を行います。もし顔が検出されれば、検出された顔の位置が出力されます。

import glob
import os

import cv2

cascade_path = cv2.data.haarcascades + 'haarcascade_frontalface_alt.xml'
cascade = cv2.CascadeClassifier(cascade_path)

for image_path in glob.glob('./src/*.jpg'):
    image_name = os.path.basename(image_path)
    print(f'image_path: {image_path} image_name: {image_name}')

    image = cv2.imread(image_path)
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    face_list = cascade.detectMultiScale(
        gray_image, 1.1, 5, minSize=(100, 100))

    if len(face_list) > 0:
        print(face_list)

実行例

image_path: ./src/DSCN0295.jpg image_name: DSCN0295.jpg
[[1818  805  353  353]]
image_path: ./src/DSCN0320.jpg image_name: DSCN0320.jpg
[[1976 1350  479  479]]
image_path: ./src/DSCN0347.jpg image_name: DSCN0347.jpg
image_path: ./src/DSCN0351.jpg image_name: DSCN0351.jpg
[[1958  437  826  826]]
image_path: ./src/DSC_6152.jpg image_name: DSC_6152.jpg
[[1210  746  377  377]
 [ 449  802  336  336]]
image_path: ./src/DSC_6322.jpg image_name: DSC_6322.jpg
[[1023 1776  204  204]
 [ 647 1856  206  206]]
image_path: ./src/DSC_6509.jpg image_name: DSC_6509.jpg
[[2616  307  187  187]
 [ 754  247  228  228]
 [ 911 1555  260  260]]
以下略

課題9-3 顔の検出と結果の出力

指示

./srcにある画像から、顔の検出を行うプログラムを作りましょう。検出された顔は./faceに、検出された位置は元の画像に白枠を描いたものを./face_rectangleに格納してください。

回答例

import glob
import os

import cv2

cascade_path = cv2.data.haarcascades + 'haarcascade_frontalface_alt.xml'
cascade = cv2.CascadeClassifier(cascade_path)
WHITE = (255, 255, 255)

for image_path in glob.glob('./src/*.jpg'):
    image_name = os.path.basename(image_path)
    print(f'image_path: {image_path} image_name: {image_name}')

    image = cv2.imread(image_path)
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    face_list = cascade.detectMultiScale(
        gray_image, 1.1, 5, minSize=(100, 100))

    if len(face_list) > 0:
        print(face_list)
        for x, y, w, h in face_list:
            face_image = image[y: y + h, x: x + w]
            face_path = f'./face/{ image_name[:-4] }_{ x }-{ y }.jpg'
            cv2.imwrite(face_path, face_image)
        for x, y, w, h in face_list:
            cv2.rectangle(image, (x, y), (x + w, y + h), WHITE, 2)
    cv2.imwrite('./face_rectangle/' + image_name, image)

実行例

検出結果
切り出された顔画像1
切り出された顔画像2
切り出された顔画像3

0
2
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
0
2