Uma postagem feita pela equipe de desenvolvimento XR da KDDI & Alpha-U
As informações, os usos e as aplicações expressas na postagem abaixo são exclusivamente do nosso autor convidado, a KDDI.
Os VTubers, ou YouTubers virtuais, são artistas on-line que usam um avatar virtual gerado por computação gráfica. Essa tendência digital teve origem no Japão em meados da década de 2010 e se tornou um fenômeno on-line internacional. A maioria dos VTubers são YouTubers que falam inglês e japonês ou usuários que fazem transmissões ao vivo e usam designs de avatar.
A KDDI, uma operadora de telecomunicações no Japão com mais de 40 milhões de clientes, queria experimentar várias tecnologias criadas em sua rede 5G, mas descobriu que ter movimentos precisos e expressões faciais semelhantes às humanas em tempo real era um desafio.
Anunciada em maio, no Google I/O 2023, a solução MediaPipe Face Landmarker detecta pontos de referência faciais e gera pontuações de blendshape para renderizar um modelo de rosto 3D que corresponda ao usuário. Com a solução MediaPipe Face Landmarker, a KDDI e a equipe de inovação de parceiros do Google deram realismo aos avatares.
Com o poderoso e eficiente pacote Python do MediaPipe, os desenvolvedores da KDDI conseguiram detectar as características faciais do artista e extrair 52 blendshapes em tempo real.
import mediapipe as mp
from mediapipe.tasks import python as mp_python
MP_TASK_FILE = "face_landmarker_with_blendshapes.task"
class FaceMeshDetector:
def __init__(self):
with open(MP_TASK_FILE, mode="rb") as f:
f_buffer = f.read()
base_options = mp_python.BaseOptions(model_asset_buffer=f_buffer)
options = mp_python.vision.FaceLandmarkerOptions(
base_options=base_options,
output_face_blendshapes=True,
output_facial_transformation_matrixes=True,
running_mode=mp.tasks.vision.RunningMode.LIVE_STREAM,
num_faces=1,
result_callback=self.mp_callback)
self.model = mp_python.vision.FaceLandmarker.create_from_options(
options)
self.landmarks = None
self.blendshapes = None
self.latest_time_ms = 0
def mp_callback(self, mp_result, output_image, timestamp_ms: int):
if len(mp_result.face_landmarks) >= 1 and len(
mp_result.face_blendshapes) >= 1:
self.landmarks = mp_result.face_landmarks[0]
self.blendshapes = [b.score for b in mp_result.face_blendshapes[0]]
def update(self, frame):
t_ms = int(time.time() * 1000)
if t_ms <= self.latest_time_ms:
return
frame_mp = mp.Image(image_format=mp.ImageFormat.SRGB, data=frame)
self.model.detect_async(frame_mp, t_ms)
self.latest_time_ms = t_ms
def get_results(self):
return self.landmarks, self.blendshapes
O Firebase Realtime Database armazena uma coleção de 52 valores flutuantes de blendshape. Cada linha corresponde a um blendshape específico, listado em ordem.
_neutral,
browDownLeft,
browDownRight,
browInnerUp,
browOuterUpLeft,
...
Esses valores de blendshape são continuamente atualizados em tempo real conforme a câmera está aberta e o modelo FaceMesh está em execução. Com cada frame, o banco de dados reflete os valores de blendshape mais recentes, capturando as mudanças dinâmicas nas expressões faciais detectadas pelo modelo FaceMesh.
Após extrair os dados dos blendshapes, a próxima etapa envolve a transmissão para o Firebase Realtime Database. Esse sistema de banco de dados avançado garante um fluxo contínuo de dados em tempo real para os clientes, eliminando preocupações sobre a escalonabilidade do servidor e permitindo que a KDDI se concentre em oferecer uma experiência simplificada ao usuário.
import concurrent.futures
import time
import cv2
import firebase_admin
import mediapipe as mp
import numpy as np
from firebase_admin import credentials, db
pool = concurrent.futures.ThreadPoolExecutor(max_workers=4)
cred = credentials.Certificate('your-certificate.json')
firebase_admin.initialize_app(
cred, {
'databaseURL': 'https://your-project.firebasedatabase.app/'
})
ref = db.reference('projects/1234/blendshapes')
def main():
facemesh_detector = FaceMeshDetector()
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
facemesh_detector.update(frame)
landmarks, blendshapes = facemesh_detector.get_results()
if (landmarks is None) or (blendshapes is None):
continue
blendshapes_dict = {k: v for k, v in enumerate(blendshapes)}
exe = pool.submit(ref.set, blendshapes_dict)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
exit()
Para continuar o progresso, os desenvolvedores transmitem perfeitamente os dados de blendshapes do Firebase Realtime Database para as instâncias de Immersive Stream para XR do Google Cloud em tempo real. O Immersive Stream para XR do Google Cloud é um serviço gerenciado que executa projetos Unreal Engine na nuvem, renderiza e transmite experiências fotorrealistas imersivas em 3D e realidade aumentada (RA) para smartphones e navegadores em tempo real.
Essa integração permite que a KDDI conduza animação facial de personagens e consiga streaming de animação facial em tempo real com latência mínima, garantindo uma experiência envolvente ao usuário.
No lado do Unreal Engine executado pelo Immersive Stream para XR, usamos o SDK do Firebase para C++ a fim de receber dados do Firebase perfeitamente. Ao estabelecer um listener de banco de dados, podemos recuperar instantaneamente os valores do blendshape assim que ocorrerem atualizações na tabela do Firebase Realtime Database. Essa integração permite acesso em tempo real aos dados mais recentes do blendshape, permitindo animação facial dinâmica e responsiva em projetos do Unreal Engine.
Depois de recuperar os valores do blendshape do SDK do Firebase, podemos conduzir a animação facial no Unreal Engine usando o nó "Modify Curve" no blueprint da animação. Cada valor de blendshape é atribuído ao personagem individualmente em cada frame, permitindo controle preciso e em tempo real sobre as expressões faciais do personagem.
Uma abordagem eficaz para implementar um listener de banco de dados em tempo real no Unreal Engine é usar o subsistema GameInstance, que serve como um padrão singleton alternativo. Isso permite a criação de uma instância BlendshapesReceiver dedicada e responsável por lidar com a conexão, autenticação e recepção contínua de dados do banco de dados em segundo plano.
Com o subsistema GameInstance, a instância BlendshapesReceiver pode ser instanciada e mantida durante toda a sessão do jogo. Isso garante uma conexão persistente com o banco de dados enquanto o blueprint da animação lê e conduz a animação facial usando os dados recebidos do blendshape.
Com apenas um PC local executando o MediaPipe, a KDDI conseguiu capturar a expressão facial e o movimento do artista e criou animações 3D de alta qualidade em tempo real.
A KDDI está colaborando com desenvolvedores de moda de anime do Metaverso, como a Adastria Co., Ltd.
Para saber mais, assista às sessões do Google I/O 2023: ML fácil no dispositivo com o MediaPipe, Turbinar seu app da Web com aprendizado de máquina e MediaPipe e Novidades do aprendizado de máquina. Confira também a documentação oficial em developers.google.com/mediapipe.
Esta integração do MediaPipe é um exemplo de como a KDDI está eliminando a fronteira entre os mundos real e virtual, permitindo aos usuários desfrutar de experiências cotidianas, como assistir apresentações de música ao vivo, apreciar a arte, conversar com amigos e fazer compras quando e onde quiserem.
O αU da KDDI oferece serviços para a era Web3, incluindo metaverso, transmissão ao vivo e compras virtuais, moldando um ecossistema em que qualquer pessoa pode se tornar um criador, apoiando a nova geração de usuários que se movem facilmente entre os mundos real e virtual.