MediaPipe ã§ãã¼ãã£ã« ãã¥ã¼ãã³ããããªã¢ã«ã«
KDDI ã¯ãã¼ãã£ã« ãã¥ã¼ãã³『ã¡ã¿ã³』ã«ããã¹ãèªã¿ä¸ãæ©è½ã¨ã¯ã©ã¦ã ã¬ã³ããªã³ã°æè¡ãçµ±å |
VTuber(ãã¼ãã£ã« YouTuber)ã¯、ã³ã³ãã¥ã¼ã¿ ã°ã©ãã£ãã¯ã¹ã«ãã£ã¦çæããããã¼ãã£ã« ã¢ãã¿ã¼ã使ç¨ãããªã³ã©ã¤ã³ ã¨ã³ã¿ã¼ãã¤ãã¼ã§ã。ãã®ãã¸ã¿ã« ãã¬ã³ã㯠2010 年代åã°ã«æ¥æ¬ã§å§ã¾ã、ãªã³ã©ã¤ã³ã§å½éçã«æ´»åããç¾è±¡ãèµ·ããã¾ãã。ã»ã¨ãã©ã® VTuber ã¯、ã¢ãã¿ã¼ã®ãã¶ã¤ã³ã使ç¨ãã YouTuber ã¾ãã¯ã©ã¤ãé ä¿¡è ã§、è±èªã¨æ¥æ¬èªã®ä¸¡æ¹ã話ãã¾ã。
KDDI ã¯、4,000 ä¸äººä»¥ä¸ã®é¡§å®¢ãæã¤æ¥æ¬ã®éä¿¡äºæ¥è ã§ã。5G ãããã¯ã¼ã¯ä¸ã«æ§ç¯ããããã¾ãã¾ãªãã¯ããã¸ã¼ã®å®é¨ãéãã¦、VTuber ã®ãããªãé²åãæ¯æ´ãããã¨èãã¦ãã¾ããã、æ£ç¢ºãªåãã人éããã表æ ããªã¢ã«ã¿ã¤ã ã§è¡¨ç¾ãããã¨ã¯å°é£ãªèª²é¡ã§ãã。
5 æã® Google I/O 2023 ã§çºè¡¨ããã MediaPipe ã®ãã§ã¤ã¹ ã©ã³ããã¼ã«ã¼ (è±èª) ã½ãªã¥ã¼ã·ã§ã³ã¯、é¡ã®ã©ã³ããã¼ã¯ãæ¤åºã、ãã¬ã³ãã·ã§ã¤ã ã¹ã³ã¢ãåºåãã¦、ã¦ã¼ã¶ã¼ã®è¡åã«å³ãã 3D ã®é¡ã¢ãã«ãã¬ã³ããªã³ã°ãããã®ã§ã。KDDI ã¯、Google ãã¼ããã¼ ã¤ããã¼ã·ã§ã³ ãã¼ã ã¨å ±å㧠MediaPipe ãã§ã¤ã¹ ã©ã³ããã¼ã«ã¼ ã½ãªã¥ã¼ã·ã§ã³ã使ç¨ãã¦ãã¹ããå®æ½ã、ãã¼ãã£ã« ãã¥ã¼ãã³ã«ç¾å®æããããããã¨ã«æåãã¾ãã。
æè¡å®è£
KDDI ã®ãããããã¼ã¯、Mediapipe ã®å¼·åã§å¹çç㪠Python ããã±ã¼ã¸ã使ç¨ãããã¨ã§、ããã©ã¼ãã¼ã®é¡ã®ç¹å¾´ãæ¤åºã、52 åã®ãã¬ã³ãã·ã§ã¤ãããªã¢ã«ã¿ã¤ã ã§æ½åºã§ãã¾ãã。
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
_neutral,
browDownLeft,
browDownRight,
browInnerUp,
browOuterUpLeft,
...
ãã¬ã³ãã·ã§ã¤ã ãã¼ã¿ãæ½åºããã、次ã®ã¹ãããã§ã¯ãã®ãã¼ã¿ã Firebase Realtime Database ã«éä¿¡ãã¾ã。ãã®é«åº¦ãªãã¼ã¿ãã¼ã¹ ã·ã¹ãã ãæ´»ç¨ãããã¨ã§、ãªã¢ã«ã¿ã¤ã ãã¼ã¿ãã·ã¼ã ã¬ã¹ã«ã¯ã©ã¤ã¢ã³ãã«è»¢éãã、ãµã¼ãã¼ã®ã¹ã±ã¼ã©ããªãã£ã«é¢ããæ¸å¿µã解æ¶ããã¾ã。ãã®ãã KDDI ã¯、ã¦ã¼ã¶ã¼ ã¨ã¯ã¹ããªã¨ã³ã¹ãå¹çåãããã¨ã«éä¸ã§ãã¾ã。
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()
ããã«、ãããããã¼ã¯、ãã¬ã³ãã·ã§ã¤ã ãã¼ã¿ã Firebase Realtime Database ãã Google Cloud ã® Immersive Stream for XR ã¤ã³ã¹ã¿ã³ã¹ã«ãªã¢ã«ã¿ã¤ã ã§ã·ã¼ã ã¬ã¹ã«éä¿¡ãã¾ã。Google Cloud ã® Immersive Stream for XR ã¯、ã¯ã©ã¦ãå´ã§ Unreal Engine ããã¸ã§ã¯ããå®è¡ã、åçã®ããã«ãªã¢ã«ã§æ²¡å ¥æã®ãã 3D ãæ¡å¼µç¾å®(AR)ã¨ã¯ã¹ããªã¨ã³ã¹ããªã¢ã«ã¿ã¤ã ã§ã¹ãã¼ããã©ã³ããã©ã¦ã¶ã«ã¹ããªã¼ãã³ã°ãã¦ã¬ã³ããªã³ã°ããããã¼ã¸ã ãµã¼ãã¹ã§ã。
ãã®çµ±åã«ãã KDDI ã¯、ãã£ã©ã¯ã¿ã¼ã®ãã§ã¤ã·ã£ã« ã¢ãã¡ã¼ã·ã§ã³ãæå°éã®ã¬ã¤ãã³ã·ã§ãªã¢ã«ã¿ã¤ã ã«ã¹ããªã¼ãã³ã°ã、æ²¡å ¥åã®ã¦ã¼ã¶ã¼ ã¨ã¯ã¹ããªã¨ã³ã¹ã確å®ã«æä¾ã§ããããã«ãªãã¾ãã。
Immersive Stream for XR ã«ãã£ã¦å®è¡ããã Unreal Engine å´ã§ã¯、Firebase C++ SDK ã使ç¨ã㦠Firebase ãããã¼ã¿ãã·ã¼ã ã¬ã¹ã«åä¿¡ãã¾ã。ãã¼ã¿ãã¼ã¹ ãªã¹ãã¼ã確ç«ãããã¨ã«ãã、Firebase Realtime Database ã®ãã¼ãã«ã§æ´æ°ãçºçãããããã«ãã¬ã³ãã·ã§ã¤ãå¤ãåå¾ã§ãã¾ã。ãã®çµ±åã«ãã、ææ°ã®ãã¬ã³ãã·ã§ã¤ã ãã¼ã¿ã«ãªã¢ã«ã¿ã¤ã ã§ã¢ã¯ã»ã¹ã§ããããã«ãªããã、Unreal Engine ããã¸ã§ã¯ãã«ããã¦åçã§å¿çæ§ã®é«ããã§ã¤ã·ã£ã« ã¢ãã¡ã¼ã·ã§ã³ãå®ç¾ã§ãã¾ã。
Unreal Engine ã«ãªã¢ã«ã¿ã¤ã ãã¼ã¿ãã¼ã¹ ãªã¹ãã¼ãå¹æçã«å®è£ ããã«ã¯、代æ¿ã®ã·ã³ã°ã«ãã³ ãã¿ã¼ã³ã¨ã㦠GameInstance ãµãã·ã¹ãã ãå©ç¨ãã¾ã。ããã«ãã、ãã¼ã¿ãã¼ã¹æ¥ç¶、èªè¨¼、ããã¯ã°ã©ã¦ã³ãã§ã®ç¶ç¶çãªãã¼ã¿åä¿¡ã®å¦çãæ ãå°ç¨ã® BlendshapesReceiver ã¤ã³ã¹ã¿ã³ã¹ãä½æã§ãã¾ã。
GameInstance ãµãã·ã¹ãã ãå©ç¨ããã¨、BlendshapesReceiver ã¤ã³ã¹ã¿ã³ã¹ãä½æãã¦、ã²ã¼ã ã»ãã·ã§ã³ã®åç¶æéå ¨ä½ã§ç¶æã§ãã¾ã。ããã«ãã、åä¿¡ãããã¬ã³ãã·ã§ã¤ã ãã¼ã¿ã使ç¨ãã¦ã¢ãã¡ã¼ã·ã§ã³ ãã«ã¼ããªã³ãããã§ã¤ã·ã£ã« ã¢ãã¡ã¼ã·ã§ã³ãèªã¿åã£ã¦å®æ½ãã¦ããé、æ°¸ç¶çãªãã¼ã¿ãã¼ã¹æ¥ç¶ã確ä¿ããã¾ã。
KDDI ã¯、MediaPipe ãå®è¡ãããã¼ã«ã« PC 1 å°ã ãã§、å®éã®ããã©ã¼ãã¼ã®è¡¨æ ã¨åãããã£ããã£ã、質ã®é«ã 3D ãªã¿ã¼ã²ãã ã¢ãã¡ã¼ã·ã§ã³ããªã¢ã«ã¿ã¤ã ã§ä½æãããã¨ã«æåãã¾ãã。
ã¯ããã«
詳細ã«ã¤ãã¦ã¯、Google I/O 2023 ã®æ¬¡ã®ã»ãã·ã§ã³ãã覧ãã ãã (åç»/è±èª æ¥æ¬èªã®èªååå¹ãã) : MediaPipe ã使ã£ãç°¡åãªãªã³ããã¤ã¹æ©æ¢°å¦ç¿、æ©æ¢°å¦ç¿ã¨ MediaPipe ã§ã¦ã§ãã¢ããªãå¼·åãã、æ©æ¢°å¦ç¿ã®æ°æ©è½。ã¾ã、developers.google.com/mediapipe (è±èª) ã§å ¬å¼ããã¥ã¡ã³ããã確èªãã ãã。
次ã®ã¹ããã
ãã® MediaPipe çµ±åã¯、誰ããã¯ãªã¨ã¤ã¿ã¼ã«ãªãããã¨ã³ã·ã¹ãã ãæ§ç¯ã、ç¾å®ã¨ä»®æ³ã軽ããã«è¡ãæ¥ããæ°ä¸ä»£ã®ã¦ã¼ã¶ã¼ã«å¯ãæ·»ãããã® KDDI ã®åãçµã¿ã®ä¸ä¾ã§ã。KDDI 㮠αU ã¯、ã¡ã¿ãã¼ã¹、ã©ã¤ãé
ä¿¡、ãã¼ãã£ã« ã·ã§ããã³ã°ãªã© Web3 æ代ã®ãµã¼ãã¹ãæä¾ãã¾ã。
Reviewed by Bryan Tanaka - Program Manager, Google Partner Innovation