OpenCV 顔認識

プログラミング
# 顔検出

import matplotlib.pyplot as plt
import cv2

#カスケードファイルのを指定して検出器を作成
cascade_file = "haarcascade_frontalface_alt.xml"
cascade = cv2.CascadeClassifier(cascade_file)

#画像を読みコンでグレースケールに変換する
img = cv2.imread("girl.jpg")
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#顔認識を実行
face_list = cascade.detectMultiScale(img_gray, minSize=(150,150))

#結果を確認
if len(face_list) == 0:
    print("失敗")
    quit()
    
#認識した部分に印をつける
for (x, y, w, h) in face_list:
    print("顔の座標=", x, y, w, h)
    red = (0,0,255)
    cv2.rectangle(img, (x, y), (x+w, y+h), red, thickness=20)
    
#画像を出力
cv2.imwrite("face-detect.png", img)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
# モザイク処理関数

import cv2

def mosaic(img, rect, size):
    #モザイクかける領域を取得
    (x1, y1, x2, y2) = rect
    w = x2 - x1
    h = y2 - y1
    i_rect = img[y1:y2, x1:x2]
    
    #モザイク処理のため、一度縮小して拡大する
    i_small = cv2.resize(i_rect, ( size, size))
    i_mos = cv2.resize(i_small, (w, h), interpolation=cv2.INTER_AREA)
    
    #画像にモザイク画像を重ねる
    img2 = img.copy()
    img2[y1:y2, x1:x2] = i_mos
    return img2
# モザイクをかける

import matplotlib.pyplot as plt
import cv2
#from mosaic import mosaic as mosaic

def mosaic(img, rect, size):
    (x1, y1, x2, y2) = rect
    w = x2 - x1
    h = y2 - y1
    i_rect = img[y1:y2, x1:x2]
    
    # モザイクの「粗さ」に基づいて縮小後のサイズを計算
    # 修正点: 縮小後のサイズ計算を修正
    i_small = cv2.resize(i_rect, (max(1, w // size), max(1, h // size)))
    
    # 修正点: 元のサイズに戻す際、正確に元の領域のサイズを指定
    i_mos = cv2.resize(i_small, (w, h), interpolation=cv2.INTER_AREA)
    
    img2 = img.copy()
    img2[y1:y2, x1:x2] = i_mos
    return img2



# 画像のサイズに合わせたモザイク処理領域の調整
rect = (50, 50, min(270, 450), min(187, 450))  # 画像のサイズを超えないように調整

# モザイク処理を適用
mos = mosaic(img, rect, 10)

# モザイクをかけた画像を出力
cv2.imwrite("cat-mosaic-adjusted.png", mos)
plt.imshow(cv2.cvtColor(mos, cv2.COLOR_BGR2RGB))
plt.show()
# (参考)エラーがあるので、画像のサイズを確認


img = cv2.imread("cat.jpeg")
if img is not None:
    print("画像のサイズ:", img.shape)  # (高さ, 幅, チャンネル数)を表示
else:
    print("画像が読み込めませんでした。ファイル名またはパスを確認してください。")

# モザイク処理を適用する領域を確認
rect = (50, 50, 450, 450)
if img is not None:
    h, w = img.shape[:2]
    if rect[2] > w or rect[3] > h:
        print("指定されたモザイク処理領域が画像のサイズを超えています。")
    else:
        mos = mosaic(img, rect, 10)
        # モザイクをかけた画像を出力
        cv2.imwrite("cat-mosaic.png", mos)
        plt.imshow(cv2.cvtColor(mos, cv2.COLOR_BGR2RGB))
        plt.show()
画像のサイズ: (187, 270, 3)
指定されたモザイク処理領域が画像のサイズを超えています。
# 人間の顔に自動でモザイクをかける


import matplotlib.pyplot as plt
import cv2
# from mosaic import mosaic as mosaic

def mosaic(img, rect, size):
    (x1, y1, x2, y2) = rect
    w = x2 - x1
    h = y2 - y1
    i_rect = img[y1:y2, x1:x2]
    
    # モザイクの「粗さ」に基づいて縮小後のサイズを計算
    # 修正点: 縮小後のサイズ計算を修正
    i_small = cv2.resize(i_rect, (max(1, w // size), max(1, h // size)))
    
    # 修正点: 元のサイズに戻す際、正確に元の領域のサイズを指定
    i_mos = cv2.resize(i_small, (w, h), interpolation=cv2.INTER_AREA)
    
    img2 = img.copy()
    img2[y1:y2, x1:x2] = i_mos
    return img2

#カスケードファイルを指定して分類器を作成
cascade_file = "haarcascade_frontalface_alt.xml"
cascade = cv2.CascadeClassifier(cascade_file)

#画像を読み込んでグレースケール変換
img = cv2.imread("family.jpg")
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#顔検出を実行
face_list = cascade.detectMultiScale(img_gray, minSize=(150,150))
if len(face_list) == 0 : quit()
    
#認識した部分の画像にモザイクをかける
for (x,y,w,h) in face_list:
    img = mosaic(img, (x,y,x+w,y+h),10)
    
#画像を出力
cv2.imwrite("family-mosaic.png", img)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
# OpenCVのかお検出は横顔や傾きに弱い

import matplotlib.pyplot as plt
import cv2
from scipy import ndimage

#検出器と画像の読み込み
cascade_file = "haarcascade_frontalface_alt.xml"
cascade = cv2.CascadeClassifier(cascade_file)
img = cv2.imread("girl.jpg")

#顔検出を実行し、印をつける
def face_detect(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    face_list = cascade.detectMultiScale(img_gray, minSize=(300,300))
    
    #認識した部分に印をつける
    for (x, y, w, h) in face_list:
        print("顔の座標=", x, y, w, h)
        red = (0,0,255)
        cv2.rectangle(img, (x,y), (x+w, y+h), red, thickness=30)
        
#角度ごとに検証する
for i in range(0,9):
    ang = i * 10
    print("---" + str(ang) + "---")
    img_r = ndimage.rotate(img, ang)
    face_detect(img_r)
    plt.subplot(3,3,i+1)
    plt.axis("off")
    plt.title("angle="+str(ang))
    plt.imshow(cv2.cvtColor(img_r, cv2.COLOR_BGR2RGB))
    
plt.show()
---0---
顔の座標= 319 308 405 405
---10---
顔の座標= 394 385 409 409
---20---
顔の座標= 451 444 408 408
---30---
顔の座標= 494 483 409 409
---40---
---50---
---60---
---70---
---80---
タイトルとURLをコピーしました