第13回 課題解答

元画像の例

課題1 : リサイズ

import cv2

# 画像読み込み
image = cv2.imread('source.jpg')

# 長辺が800ピクセルになるようにリサイズ
height, width = image.shape[:2]
if height > width:
  new_height = 800
  new_width = int(width * (800 / height))
else:
  new_width = 800
  new_height = int(height * (800 / width))
image = cv2.resize(image, (new_width, new_height))

# 画像を保存
cv2.imwrite('1.jpg', image)
実行結果

課題2 : パラメータによる顔検出精度の調整

import cv2

# 画像読み込み
image = cv2.imread('1.jpg')

# OpenCVのデフォルトの顔検出器を取得
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

# パラメータを変えながら顔検出を実行
for scaleFactor in [1.05, 1.1, 1.2]:
  for minNeighbors in [3, 4, 5]:
    for minSize in [(30, 30), (40, 40), (50, 50)]:
      # 顔検出を実行
      faces = face_cascade.detectMultiScale(image, scaleFactor=scaleFactor, minNeighbors=minNeighbors, minSize=minSize)
      # 結果を表示 (パラメータの値と検出数)
      print(f"scaleFactor={scaleFactor}, minNeighbors={minNeighbors}, minSize={minSize} -> {len(faces)} faces detected")
出力結果(例)
scaleFactor=1.05, minNeighbors=3, minSize=(30, 30) -> 10 faces detected
scaleFactor=1.05, minNeighbors=3, minSize=(40, 40) -> 10 faces detected
scaleFactor=1.05, minNeighbors=3, minSize=(50, 50) -> 10 faces detected
scaleFactor=1.05, minNeighbors=4, minSize=(30, 30) -> 9 faces detected
scaleFactor=1.05, minNeighbors=4, minSize=(40, 40) -> 9 faces detected
scaleFactor=1.05, minNeighbors=4, minSize=(50, 50) -> 9 faces detected
scaleFactor=1.05, minNeighbors=5, minSize=(30, 30) -> 8 faces detected
scaleFactor=1.05, minNeighbors=5, minSize=(40, 40) -> 8 faces detected
scaleFactor=1.05, minNeighbors=5, minSize=(50, 50) -> 8 faces detected
scaleFactor=1.1, minNeighbors=3, minSize=(30, 30) -> 6 faces detected
scaleFactor=1.1, minNeighbors=3, minSize=(40, 40) -> 6 faces detected
scaleFactor=1.1, minNeighbors=3, minSize=(50, 50) -> 6 faces detected
scaleFactor=1.1, minNeighbors=4, minSize=(30, 30) -> 6 faces detected
scaleFactor=1.1, minNeighbors=4, minSize=(40, 40) -> 6 faces detected
scaleFactor=1.1, minNeighbors=4, minSize=(50, 50) -> 6 faces detected
scaleFactor=1.1, minNeighbors=5, minSize=(30, 30) -> 4 faces detected
scaleFactor=1.1, minNeighbors=5, minSize=(40, 40) -> 4 faces detected
scaleFactor=1.1, minNeighbors=5, minSize=(50, 50) -> 4 faces detected
scaleFactor=1.2, minNeighbors=3, minSize=(30, 30) -> 5 faces detected
scaleFactor=1.2, minNeighbors=3, minSize=(40, 40) -> 5 faces detected
scaleFactor=1.2, minNeighbors=3, minSize=(50, 50) -> 5 faces detected
scaleFactor=1.2, minNeighbors=4, minSize=(30, 30) -> 2 faces detected
scaleFactor=1.2, minNeighbors=4, minSize=(40, 40) -> 2 faces detected
scaleFactor=1.2, minNeighbors=4, minSize=(50, 50) -> 2 faces detected
scaleFactor=1.2, minNeighbors=5, minSize=(30, 30) -> 1 faces detected
scaleFactor=1.2, minNeighbors=5, minSize=(40, 40) -> 1 faces detected
scaleFactor=1.2, minNeighbors=5, minSize=(50, 50) -> 1 faces detected

課題3 : 顔検出

import cv2

# 画像読み込み
image = cv2.imread('1.jpg')

# OpenCVのデフォルトの顔検出器を取得
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

# 顔検出を実行
faces = face_cascade.detectMultiScale(image, scaleFactor=1.05, minNeighbors=5, minSize=(30, 30))

# 検出された顔に対して処理を行う
for (x, y, w, h) in faces:
  # 顔の周りに赤い四角形を描画
  cv2.rectangle(image, (x, y), (x+w, y+h), (0, 0, 255), 2)

# 画像を保存
cv2.imwrite('3.png', image)
実行結果

課題4 : 顔にぼかしを入れる

import cv2

# 画像読み込み
image = cv2.imread('1.jpg')

# OpenCVのデフォルトの顔検出器を取得
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

# 顔検出を実行
faces = face_cascade.detectMultiScale(image, scaleFactor=1.05, minNeighbors=5, minSize=(30, 30))

# 検出された顔に対して処理を行う
for (x, y, w, h) in faces:
  # 顔の部分をぼかす
  face = image[y:y+h, x:x+w]
  blurred_face = cv2.GaussianBlur(face, (99, 99), 30)
  image[y:y+h, x:x+w] = blurred_face

# 画像を保存
cv2.imwrite('4.png', image)
実行結果

課題5 : 顔にモザイクを入れる

import cv2

# 画像読み込み
image = cv2.imread('1.jpg')

# OpenCVのデフォルトの顔検出器を取得
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

# 顔検出を実行
faces = face_cascade.detectMultiScale(image, scaleFactor=1.05, minNeighbors=5, minSize=(30, 30))

# 検出された顔に対して処理を行う
for (x, y, w, h) in faces:
  # 顔の部分にモザイクを入れる
  face = image[y:y+h, x:x+w]
  face = cv2.resize(face, (w//10, h//10))
  face = cv2.resize(face, (w, h), interpolation=cv2.INTER_NEAREST)
  image[y:y+h, x:x+w] = face

# 画像を保存
cv2.imwrite('5.png', image)
実行結果