GAN 알고리즘 가상인플루언서 만들어보기 (Make a Virtual Influencer with Colab),가상 인플루언서(메타버스)

📌가상인플루언서 장단점 및 개발 코드

  1. 비용 절감: 가상인플루언서는 실제 사람이 아니기 때문에 월급, 근로 계약, 복지 혜택 등과 같은 인적 자원에 대한 비용이 들지 않습니다. 이로 인해 기업은 인플루언서와의 협업에 대해 더 저렴하게 비용을 지출할 수 있습니다.
  2. 제작과 유지보수의 용이성: 가상인플루언서는 컴퓨터 프로그램 또는 인공지능을 기반으로 만들어지기 때문에 제작 및 운영에 대한 유연성과 용이성을 제공합니다. 기업은 캐릭터의 외모, 목소리, 스타일 등을 조정하거나 업데이트할 수 있으며, 이를 통해 브랜드 이미지와 일관성을 유지하고 새로운 캠페인에 쉽게 적용할 수 있습니다.
  3. 상시 가용성: 가상인플루언서는 언제든지 활동할 수 있습니다. 인플루언서는 실제로 일하고 쉬는 시간이 있을 수 있지만, 가상인플루언서는 24시간 동안 활동할 수 있으며, 이를 통해 더 많은 소비자에게 접근할 수 있습니다.
  4. 목표 그룹에 대한 타겟팅: 가상인플루언서는 특정 인구통계, 관심사, 행동 패턴 등을 기반으로한 정교한 타겟팅이 가능합니다. 이를 통해 기업은 자신의 제품 또는 서비스를 특정 그룹에 맞추어 홍보할 수 있으며, 효과적인 마케팅 전략을 구축할 수 있습니다.
  5. 위험 감소: 인플루언서와의 협업은 항상 일정한 위험이 따릅니다. 예를 들어, 인플루언서의 행동, 발언, 부적절한 콘텐츠 등이 논란을 일으킬 수 있습니다. 가상인플루언서는 이러한 위험을 최소화할 수 있으며, 브랜드 이미지에 대한 통제력을 높일 수 있습니다.

*차은우, 방탄소년단 진 사진을 활용

🥕 Google Colab을 활용해서 가상 인플루언서 얼굴을 만들어 보겠습니다!

2019년 11월에 NeuroIPS에서 발표된 First Order Motion Model for Image Animation 페이퍼에서 발표된 기술&코드를 포함

📌 코드

🌳 버전세팅 및 깃허브 코드 불러오기

#버전 확인 
# %를 사용하는 매직커멘드를 통해 버전 변경
# %tensorflow_version 1.x 

#keras load_model에서 오류 발생할 때
!pip install h5py==2.10.0 #:: 다운그레이드 실시로 문제 해결
import h5py
print(h5py.__version__)

🌳 인공지능 신경망 파일 및 함수 설정

🌱 import 설정 및

#임시로 각주
%tensorflow_version 1.x

import os
import cv2
import math
import pickle
import imageio
import warnings
import PIL.Image
import numpy as np
from PIL import Image
import tensorflow as tf
from random import randrange
import moviepy.editor as mpy
from google.colab import drive
from google.colab import files
import matplotlib.pyplot as plt
from IPython.display import clear_output
from moviepy.video.io.ffmpeg_writer import FFMPEG_VideoWriter
%matplotlib inline
warnings.filterwarnings("ignore")

def get_watermarked(pil_image: Image) -> Image:
  try:
    image = cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGB2BGR)
    (h, w) = image.shape[:2]
    image = np.dstack([image, np.ones((h, w), dtype="uint8") * 255])
    pct = 0.08
    full_watermark = cv2.imread('/content/BabyGAN/media/logo.png', cv2.IMREAD_UNCHANGED)
    (fwH, fwW) = full_watermark.shape[:2]
    wH = int(pct * h*2)
    wW = int((wH * fwW) / fwH*0.1)
    watermark = cv2.resize(full_watermark, (wH, wW), interpolation=cv2.INTER_AREA)
    overlay = np.zeros((h, w, 4), dtype="uint8")
    (wH, wW) = watermark.shape[:2]
    overlay[h - wH - 10 : h - 10, 10 : 10 + wW] = watermark
    output = image.copy()
    cv2.addWeighted(overlay, 0.5, output, 1.0, 0, output)
    rgb_image = cv2.cvtColor(output, cv2.COLOR_BGR2RGB)
    return Image.fromarray(rgb_image)
  except: return pil_image

def generate_final_images(latent_vector, direction, coeffs, i):
    new_latent_vector = latent_vector.copy()
    new_latent_vector[:8] = (latent_vector + coeffs*direction)[:8]
    new_latent_vector = new_latent_vector.reshape((1, 18, 512))
    generator.set_dlatents(new_latent_vector)
    img_array = generator.generate_images()[0]
    img = PIL.Image.fromarray(img_array, 'RGB')
    if size[0] >= 512: img = get_watermarked(img)
    img_path = "/content/BabyGAN/for_animation/" + str(i) + ".png"
    img.thumbnail(animation_size, PIL.Image.ANTIALIAS)
    img.save(img_path)
    face_img.append(imageio.imread(img_path))
    clear_output()
    return img

def generate_final_image(latent_vector, direction, coeffs):
    new_latent_vector = latent_vector.copy()
    new_latent_vector[:8] = (latent_vector + coeffs*direction)[:8]
    new_latent_vector = new_latent_vector.reshape((1, 18, 512))
    generator.set_dlatents(new_latent_vector)
    img_array = generator.generate_images()[0]
    img = PIL.Image.fromarray(img_array, 'RGB')
    if size[0] >= 512: img = get_watermarked(img)
    img.thumbnail(size, PIL.Image.ANTIALIAS)
    img.save("face.png")
    if download_image == True: files.download("face.png")
    return img

def plot_three_images(imgB, fs = 10):
  f, axarr = plt.subplots(1,3, figsize=(fs,fs))
  axarr[0].imshow(Image.open('/content/BabyGAN/aligned_images/father_01.png'))
  axarr[0].title.set_text("Father's photo")
  axarr[1].imshow(imgB)
  axarr[1].title.set_text("Child's photo")
  axarr[2].imshow(Image.open('/content/BabyGAN/aligned_images/mother_01.png'))
  axarr[2].title.set_text("Mother's photo")
  plt.setp(plt.gcf().get_axes(), xticks=[], yticks=[])
  plt.show()

!rm -rf sample_data
!git clone https://github.com/tg-bomze/BabyGAN.git
%cd /content/BabyGAN
!mkdir aligned_images data father_image mother_image

import config
import dnnlib
import dnnlib.tflib as tflib
from encoder.generator_model import Generator

age_direction = np.load('/content/BabyGAN/ffhq_dataset/latent_directions/age.npy')
horizontal_direction = np.load('/content/BabyGAN/ffhq_dataset/latent_directions/angle_horizontal.npy')
vertical_direction = np.load('/content/BabyGAN/ffhq_dataset/latent_directions/angle_vertical.npy')
eyes_open_direction = np.load('/content/BabyGAN/ffhq_dataset/latent_directions/eyes_open.npy')
gender_direction = np.load('/content/BabyGAN/ffhq_dataset/latent_directions/gender.npy')
smile_direction = np.load('/content/BabyGAN/ffhq_dataset/latent_directions/smile.npy')

clear_output()

🌳 구글 드라이브 설정 및 GAN 깃허브 코드 가져오기

drive.mount('/content/drive')
clear_output()
if os.path.isdir('/content/drive/My Drive/BabyGAN'):
  print("0%/100%   Copying has started")
  !cp '/content/drive/My Drive/BabyGAN/finetuned_resnet.h5' '/content/BabyGAN/data'
  !cp '/content/drive/My Drive/BabyGAN/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5' '/content/BabyGAN'
  print("50%/100%  Checkpoints copied")
  !cp '/content/drive/My Drive/BabyGAN/karras2019stylegan-ffhq-1024x1024.pkl' '/content/BabyGAN'
  !cp '/content/drive/My Drive/BabyGAN/vgg16_zhang_perceptual.pkl' '/content/BabyGAN'
  print("90%/100%  Weights copied")
  !cp '/content/drive/My Drive/BabyGAN/shape_predictor_68_face_landmarks.dat.bz2' '/content/BabyGAN'
  print("100%/100% Dictionary copied")
  clear_output()
  print("Done!")
else: raise ValueError('Please read the instructions in the block description and follow all 3 points correctly!')

🌳 가상인플루언서는 BabyGAN 소스를 활용해 만든다

사진 두개 설정 -> 두 사진의 얼굴을 추출한 후 특징을 합쳐서 가상얼굴 만든다

🌱 사진 선택1


!rm -rf /content/BabyGAN/father_image/*.*
#@markdown *이미지 **url** 이나 로컬환경에 있는 사진을 업로드 하세요.*
url = '' #@param {type:"string"}
if url == '':
  uploaded = list(files.upload().keys())
  if len(uploaded) > 1: raise ValueError('You cannot upload more than one image at a time!')
  fat = uploaded[0]
else:
  try:
    !wget $url
    fat = url.split('/')[-1]
  except BaseException:
    print("Something wrong. Try uploading a photo from your computer")

FATHER_FILENAME = "father." + fat.split(".")[-1]
os.rename(fat, FATHER_FILENAME)
father_path = "/content/BabyGAN/father_image/" + FATHER_FILENAME
!mv -f $FATHER_FILENAME $father_path

!python align_images.py /content/BabyGAN/father_image /content/BabyGAN/aligned_images
clear_output()

if os.path.isfile('/content/BabyGAN/aligned_images/father_01.png'):
  pil_father = Image.open('/content/BabyGAN/aligned_images/father_01.png')
  (fat_width, fat_height) = pil_father.size
  resize_fat = max(fat_width, fat_height)/256
  display(pil_father.resize((int(fat_width/resize_fat), int(fat_height/resize_fat))))
else: raise ValueError('No face was found or there is more than one in the photo.')
가상인플루언서
방탄소년다 진

🌱 사진 선택2

!rm -rf /content/BabyGAN/mother_image/*.*
#@markdown *이미지 **url** 이나 로컬환경에 있는 사진을 업로드 하세요.*
url = '' #@param {type:"string"}
if url == '':
  uploaded = list(files.upload().keys())
  if len(uploaded) > 1: raise ValueError('You cannot upload more than one image at a time!')
  mot = uploaded[0]
else:
  try:
    !wget $url
    mot = url.split('/')[-1]
  except BaseException:
    print("Something wrong. Try uploading a photo from your computer")

MOTHER_FILENAME = "mother." + mot.split(".")[-1]
os.rename(mot, MOTHER_FILENAME)
mother_path = "/content/BabyGAN/mother_image/" + MOTHER_FILENAME
!mv -f $MOTHER_FILENAME $mother_path

!python align_images.py /content/BabyGAN/mother_image /content/BabyGAN/aligned_images
clear_output()

if os.path.isfile('/content/BabyGAN/aligned_images/mother_01.png'):
  pil_mother = Image.open('/content/BabyGAN/aligned_images/mother_01.png')
  (mot_width, mot_height) = pil_mother.size
  resize_mot = max(mot_width, mot_height)/256
  display(pil_mother.resize((int(mot_width/resize_mot), int(mot_height/resize_mot))))
else: raise ValueError('No face was found or there is more than one in the photo.')
가상인플루언서
차은우

### 🌳 사진 합성하여 가상의 얼굴 만들기

genes_influence = 0.31 #@param {type:"slider", min:0.01, max:0.99, step:0.01}
style = "Default" #@param ["Default", "Father's photo", "Mother's photo"]
if style == "Father's photo": 
  lr = ((np.arange(1,model_scale+1)/model_scale)**genes_influence).reshape((model_scale,1))
  rl = 1-lr
  hybrid_face = (lr*first_face) + (rl*second_face)
elif style == "Mother's photo": 
  lr = ((np.arange(1,model_scale+1)/model_scale)**(1-genes_influence)).reshape((model_scale,1))
  rl = 1-lr
  hybrid_face = (rl*first_face) + (lr*second_face)
else: hybrid_face = ((1-genes_influence)*first_face)+(genes_influence*second_face)
#@markdown **Virtual human's approximate age:**
person_age = 30 #@param {type:"slider", min:10, max:50, step:1}
intensity = -((person_age/5)-6)
#@markdown ---
#@markdown **Download the final image?**
download_image = False #@param {type:"boolean"}
#@markdown **Resolution of the downloaded image:**
resolution = "1024" #@param [256, 512, 1024]
size = int(resolution), int(resolution)

face = generate_final_image(hybrid_face, age_direction, intensity)
plot_three_images(face, fs = 15)

🥕 왼쪽 사진 & 오른쪽 사진 GAN알고리즘으로 합쳐져서 가상의 얼굴 생성(가운데 사진)

가상인플루언서
가상인플루언서

🌳 가상인플루언서 얼굴 제작 결과

아래 사진 클릭하면 영상 나옵니다!

가상인플루언서
가상인플루언서

📌 License

  • 2019년 11월에 NeuroIPS에서 발표된 First Order Motion Model for Image Animation 페이퍼에서 발표된 기술&코드를 포함

✔ 깃허브! 아래 사진을 클릭하면 제작에 사용된 코드를 볼수 있음!

One thought on “GAN 알고리즘 가상인플루언서 만들어보기 (Make a Virtual Influencer with Colab),가상 인플루언서(메타버스)

  1. 안녕하세요 google colab 에서 위 코드를 실행해보려고 하는데 계속 구글 드라이브 설정 및 gan 깃허브 코드 가져오기 부분에서 ValueError: Please read the instructions in the block description and follow all 3 points correctly! 라는 에러가 계속 발생합니다. 해결책을 알 수 있을까요

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다