Last active
March 31, 2024 11:19
-
-
Save ksasao/9825df29da23e7bdbbf11bbd74383653 to your computer and use it in GitHub Desktop.
顔を検出し、顔をぼかすプログラム https://twitter.com/ksasao/status/1774385456324784130
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 顔を検出し、顔をぼかすプログラム | |
# opencv-python >= 4.9.0.80 | |
import cv2 | |
import numpy as np | |
# 円形領域にぼかしを適用 | |
def circle_blur(img, rect): | |
# rectを囲む円形領域を求め、さらにそれを囲むような矩形を求める | |
center_x = int(rect[0] + rect[2] // 2) | |
center_y = int(rect[1] + rect[3] // 2) | |
r = int(np.sqrt(rect[2]**2 + rect[3]**2) / 2) | |
x = max(0,int(center_x-r)) | |
y = max(0,int(center_y-r)) | |
w = min(img.shape[1],int(center_x+r)) - x | |
h = min(img.shape[0],int(center_y+r)) - y | |
roi_rect = (x,y,w,h) | |
# 指定した領域を切り抜く | |
src_roi = img[roi_rect[1]:roi_rect[1] + roi_rect[3], roi_rect[0]:roi_rect[0] + roi_rect[2]] | |
# ガウシアンフィルタを適用 | |
sigma = r//5 # 元画像のぼかしサイズ | |
sigma_mask = r//5 # マスクのぼかしサイズ | |
dst_roi = cv2.GaussianBlur(src_roi, (0, 0), sigma) | |
dst_mask = cv2.circle(np.zeros_like(src_roi), (w//2,h//2), r-sigma_mask//2, (255,255,255), thickness=-1) | |
dst_mask = cv2.GaussianBlur(dst_mask, (0, 0), sigma_mask//2)/255 | |
# 切り抜いた画像とぼかした画像をマスクの値をもとに合成 | |
blended_roi = src_roi * (1 - dst_mask) + dst_roi * dst_mask | |
# ぼかした領域を元の画像に戻す | |
img[roi_rect[1]:roi_rect[1] + roi_rect[3], roi_rect[0]:roi_rect[0] + roi_rect[2]] = blended_roi | |
return img | |
# 画像を読み込む(適切なパスを指定してください) | |
image_path = "partyPAUI2142_TP_V.jpg" | |
img = cv2.imread(image_path) | |
# YuNetのモデルは下記から入手してください | |
# https://github.com/opencv/opencv_zoo/tree/main/models/face_detection_yunet | |
face_detector = cv2.FaceDetectorYN.create("face_detection_yunet_2023mar.onnx", "", (0, 0)) | |
# 入力サイズを指定する | |
height, width, _ = img.shape | |
face_detector.setInputSize((width, height)) | |
# 顔を検出する | |
_, faces = face_detector.detect(img) | |
for face in faces: | |
rect = face[0:4] | |
img = circle_blur(img, rect) | |
# 画像を表示 | |
cv2.imshow("Smooth Blending", img) | |
cv2.waitKey(0) | |
cv2.destroyAllWindows() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment