이번시간에는 지난시간에 만든 아바타를 가지고 움직이게 만들어 볼거에요. 지난 시간에 만든 코드에 덧붙여서 만들거에요. 반드시 지난 시간 코드를 알고 계셔야합니다.
코드의 맨 마지막에 아래 코드를 추가합니다. 아래 코드는 기존에 이미지와 동영상프레임 이미지들에서 획득한 얼굴이미지들을 하나씩 돌면서 RGB형식으로 만들어진 이미지를 BGR로 변환합니다.
opencv_images = [cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR) for img in faces]
그리고 아바타에 움직을 추가할 함수, animate_avatar()를 선언합니다. 인자로는 얼굴 이미지들을 넘겨받고, 이미지들을 빠르게 돌려서 움직이는 것 처럼 보이게 만듭니다.
def animate_avatar(images):
cv2.namedWindow('Avatar Animation', cv2.WINDOW_NORMAL)
for i in range(30): # Number of animation cycles
for image in images:
cv2.imshow('Avatar Animation', image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
# Animate the avatar
animate_avatar(opencv_images)
아래는 완성된 코드입니다.
import os
import cv2
import dlib
import numpy as np
from PIL import Image
def get_files_with_extensions(directory, extensions):
# get multiple files
files = os.listdir(directory)
if len(extensions) > 0:
return [f for f in files if os.path.splitext(f)[1].lower() in extensions]
else:
return files
# dlib 얼굴 검출기 로드
detector = dlib.get_frontal_face_detector()
# 이미지에서 얼굴을 추출하는 함수
def extract_face(image_path):
image = cv2.imread(image_path)
faces = detector(image)
if len(faces) > 0:
face = faces[0] # 발견된 첫 번째 얼굴 추출
x, y, w, h = face.left(), face.top(), face.width(), face.height()
face_image = image[y:y+h, x:x+w]
return cv2.cvtColor(face_image, cv2.COLOR_BGR2RGB)
else :
return None
# 여러 얼굴을 추출하여 반환
def extract_faces_from_arr(image_paths):
faces = []
for path in image_paths:
face = extract_face(path)
if face is not None :
faces.append(face)
return faces
# 얼굴과 비디오 프레임을 합성 아바타로 통합하는 함수
def extract_faces_from_folder(frame_dir):
# 프레임에서 얼굴 추출하여 배열에 저장
frame_faces = []
for frame_file in get_files_with_extensions(frame_dir, ['.jpg', '.png']):
frame_path = os.path.join(frame_dir, frame_file)
frame_image = extract_face(frame_path) # extract_face 함수 재사용
if frame_image is not None :
frame_faces.append(frame_image)
return frame_faces
def merge_faces(image_faces, frame_faces):
return image_faces + frame_faces
def animate_avatar(images):
cv2.namedWindow('Avatar Animation', cv2.WINDOW_NORMAL)
for i in range(30): # Number of animation cycles
for image in images:
cv2.imshow('Avatar Animation', image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
# 얼굴을 추출할 이미지 경로
image_paths = ['image1.png', 'image2.png', 'image3.png']
image_faces = extract_faces_from_arr(image_paths)
# 동영상 추출 프레임 이미지 폴더 경로
folder_path = 'frames'
frame_faces = extract_faces_from_folder(folder_path)
all_faces = merge_faces(image_faces, frame_faces)
# Convert the PIL images to OpenCV format for animation
opencv_images = [cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR) for img in all_faces]
# Animate the avatar
animate_avatar(opencv_images)
실행을 해보도록 하겠습니다. 본 파일을 실행전에 얼굴에 사용할 이미지 3개와 동영상에서 캡쳐한 프레임이미지들이 frames에 들어있는지 확인한 뒤 실행합니다.
python animate_avatar.py
실행을 하면 팝업이 하나 뜨는데 그 안에서 지금까지 생성한 얼굴들이 빠르게 돌아갑니다. 중간에 멈추고 싶을때는 Ctrl+C를 누르면 종료합니다.
아직까지는 그닥 아바타 같아보이지가 않아서, 상용화가 가능하도록 다듬는 부분에 있어서는 아무래도 따로 리서치를 해서 추가로 블로깅을 해야할것 같습니다. 생각보다 실망스러운데 일단 다음시간에 하는 더빙까지 붙여 보도록 하겠습니다.