Akjava's picture
iniit
81e69dc
"""
create_no_mouth.py
open_mouth.pyの一部
口のない画像を作ります。
口の部分のをlandpointを取って、その部分を消して、inpaintします。
inpaint部分をぼかして、元の画像の上にはりつけ、ぼかします。
著者: Akihito Miyazaki
作成日: 2024-04-23
更新履歴:
- 2024-04-23: 最初のリリース
"""
import cv2
import numpy as np
from PIL import Image
import lip_utils
from glibvision.cv2_utils import blend_rgb_images
from glibvision.numpy_utils import apply_binary_mask_to_image
def process_create_no_mouth_image(img,landmarks_list):
img_h, img_w = lip_utils.get_image_size(img)
## 口の範囲をInpaintで消す。
(bottom_width,bottom_height)=lip_utils.get_bottom_lip_width_height(landmarks_list)
lip_points = lip_utils.get_lip_mask_points(landmarks_list)
# 選択範囲を丸めてみたけど、それほどメリットが感じなかった。
#lip_points = lip_utils.bulge_polygon(lip_points,0.1)
# 唇のマスク範囲を検証
if lip_utils.DEBUG:
img_lined = np.copy(img)
cv2.polylines(img_lined, [np.array(lip_points)], isClosed=True, color=(0,255,0), thickness=1)
cv2.imwrite("create_no_mouth_image_polyline.jpg",img_lined)
# 唇のエッジ部分は、影やら、ピンクなどあるので、それを削るのに、下唇の高さを元にしている。0.5は根拠ない。
dilation_size = int(bottom_height*0.5)
lip_mask = lip_utils.create_mask_from_points(img,lip_points,dilation_size,0) # inpaintで使うので、ぼかしは不要
if lip_utils.DEBUG:
lip_utils.print_numpy(lip_mask,"lip mask")
if lip_utils.DEBUG:
cv2.imwrite("create_no_mouth_image_mask.jpg",lip_mask)
img_inpainted = cv2.inpaint(img, lip_mask,3, cv2.INPAINT_TELEA)
if lip_utils.DEBUG:
cv2.imwrite("create_no_mouth_image_inpaint.jpg",img_inpainted)
## Inpaintした部分をぼかしている。
blurred_image = cv2.GaussianBlur(img_inpainted, (29, 29), 0) #場合によっては奇数じゃないとエラーが出ることがある
if lip_utils.DEBUG:
cv2.imwrite("create_no_mouth_image_blurred.jpg",blurred_image)
apply_binary_mask_to_image(img_inpainted,blurred_image,lip_mask)
if lip_utils.DEBUG:
cv2.imwrite("create_no_mouth_image_blurred1_applied.jpg",blurred_image)
# 全体を少しぼかす
blurred_image2 = cv2.GaussianBlur(img_inpainted, (9, 9), 0)
if lip_utils.DEBUG:
cv2.imwrite("create_no_mouth_image_blurred2.jpg",blurred_image2)
# Inpaintの境界線から少し広げている
kernel = np.ones((8, 8), np.uint8)
lip_mask = cv2.dilate(lip_mask, kernel, iterations=1)
# 全体を少しぼかす
blurred_mask = cv2.GaussianBlur(lip_mask, (19, 19), 0)
if lip_utils.DEBUG:
cv2.imwrite("create_no_mouth_image_blurred_mask.jpg",blurred_mask)
# https://github.com/akjava/lip_recognition_tools/issues/12
#cv2_utils.apply_binary_mask_to_image(img_inpainted,blurred_image2,lip_mask)
img_inpainted = blend_rgb_images(img_inpainted,blurred_image2,lip_mask)
if lip_utils.DEBUG:
cv2.imwrite("create_no_mouth_image_merged.jpg",img_inpainted)
return img_inpainted
if __name__ == "__main__":
# 画像ファイルのパス
img_path = "straight.jpg"
img = cv2.imread(img_path)
landmarks_list = lip_utils.image_to_landmarks_list(img)
process_create_no_mouth_image(img,landmarks_list)