Akjava's picture
iniit
81e69dc
"""
close_eye.py
目を閉じた画像を作ります。
目と上まつ毛の部分をポイントとしており、そこをinpaintします。
inpaint部分をぼかして、元の画像の上にはりつけ、ぼかします。
著者: Akihito Miyazaki
作成日: 2024-04-23
更新履歴:
- 2024-04-23: 最初のリリース
- 2024-09-24: name suffixを追加
- 2034-11-15: changed for huggingface
"""
import os
import cv2
import numpy as np
from glibvision.numpy_utils import bulge_polygon
from glibvision.cv2_utils import fill_points,get_image_size,gray3d_to_2d,blend_rgb_images,create_color_image
from landmarks68_utils import get_left_upper_eyelid_points,get_right_upper_eyelid_points,get_bulged_eyes,get_close_eyelid_point
def create_eyelid_mask(image,face_landmarks_list,thick = 1,bulge=0.2):
black = create_color_image(image,(0,0,0))
left_eyelid = get_left_upper_eyelid_points(face_landmarks_list)
left_eyelid = bulge_polygon(left_eyelid,bulge)
fill_points(black,left_eyelid)
print("right")
right_eyelid = get_right_upper_eyelid_points(face_landmarks_list)
print(right_eyelid)
right_eyelid = bulge_polygon(right_eyelid,bulge)
fill_points(black,right_eyelid)
eyes_points = get_bulged_eyes(face_landmarks_list)
for points in eyes_points:
np_points = np.array(points,dtype=np.int32)
cv2.fillPoly(image, [np_points], (255,255,255))
if thick > 0:
cv2.polylines(black, [np_points], isClosed=False, color=(255,255,255), thickness=thick)
return cv2.cvtColor(black,cv2.COLOR_BGR2GRAY)
DEBUG = False
def process_close_eyes_image(img,landmarks_list,eyelid_thick=1,eyelid_blur=9,inpaint_radius=10,inpaint_blur=30,mask_dilate=10,dilate_blur=10):
img_h, img_w = get_image_size(img)
eyelid_mask = create_eyelid_mask(img,landmarks_list)
if DEBUG:
cv2.imwrite("close_eye_mask.jpg",eyelid_mask)
mask = gray3d_to_2d(eyelid_mask)
img_inpainted = cv2.inpaint(img, mask,inpaint_radius, cv2.INPAINT_TELEA)
if DEBUG:
cv2.imwrite("close_eye_inpaint.jpg",img_inpainted)
## Inpaintした画像をぼかす。
if inpaint_blur>0:
if inpaint_blur%2==0: #if even it would error
inpaint_blur+=1
blurred_image = cv2.GaussianBlur(img_inpainted, (inpaint_blur, inpaint_blur), 0)
if DEBUG:
cv2.imwrite("close_eye_inpaint_burred.jpg",blurred_image)
else:
blurred_image=img_inpainted
# まつげを描く
if eyelid_thick>0:
left,right = get_close_eyelid_point(landmarks_list)
for points in [left,right]:
print("## draw eyelid")
print(points)
cv2.polylines(blurred_image, [np.array(points)], isClosed=False, color=(0,0,0), thickness=eyelid_thick,lineType=cv2.LINE_AA)
if DEBUG:
cv2.imwrite("close_eye_inpaint_burred_eyeline.jpg",blurred_image)
if eyelid_thick>0 and eyelid_blur>0:
if eyelid_blur%2==0:
eyelid_blur+=1
# blur-eyelid-line
blurred_image = cv2.GaussianBlur(blurred_image, (eyelid_blur, eyelid_blur), 2)
print(mask_dilate,dilate_blur)
if mask_dilate>0:
# Inpaintの境界線から少し広げている
kernel = np.ones((mask_dilate, mask_dilate), np.uint8)
extend_mask = cv2.dilate(mask, kernel, iterations=1)
if dilate_blur>0:
if dilate_blur%2==0:
dilate_blur+=1
extend_burred_mask = cv2.GaussianBlur(extend_mask, (dilate_blur, dilate_blur), 1)
else:
extend_burred_mask = extend_mask
else:
extend_burred_mask=mask
img_inpainted = blend_rgb_images(img,blurred_image,extend_burred_mask)
if DEBUG:
cv2.imwrite("create_no_mouth_image_merged.jpg",img_inpainted)
return img_inpainted,extend_burred_mask