1枚のアニメ顔を感情豊かに動かすための手法---ポーズデータを抽象化して自在に動かす
詳細は別途になります。何ができるかとコードの公開です。
Talking-Head-AnimeFace-3による1枚絵からのリアルタイムな動画生成の最終版です。ポーズデータという扱いづらい配列ではなく、抽象化した指示で容易にキャラクタを動かすためのラッパーです。一つ前記事の通りにサーバを動かし、クライアント側をmultiproccesinngで並列処理することで、データ処理の各プロセスをサブプロセスに分散して高速化を行いました。
並列化されるプロセス
1)画像生成サーバ
2)アップスケールサーバ
3)画像生成サーバ通信プロセス
4)アップスケールサーバ通信プロセス
5)ここはMP処理ではなく3)4)をうまく呼び出すためのメソッド(Dictionary形式またはPack形式ポーズデータからアップスケールされた
画像を得るためのメソッド)
6)各抽象データのリクエストをまとめて指定された間隔で5)を呼び出す
サンプル画像
最後のテストコードを動かすと以下のような画像がスムースに変化していく様子がリアルタイムで生成されて動画に見えます。
(サンプル画像は例なのでもっと複雑な動きします)
使える抽象化メソッド
以下、 timeはリクエスするポーズに変化する秒の指定
current_pose_dicは現在のポーズDictionary
1) wink(瞬きも)ポーズリクエスト
pose_wink(self,l_r, time,current_pose_dic)
2)瞳ポーズリクエスト(左右同時に簡略化) 通常はこちら
pose_iris(self, iris_small, iris_rotation, time,current_pose_dic)
3)瞳ポーズリクエスト(左右個別)
def pose_iris_sp(self, iris_l, iris_r, iris_x,iris_y,time,current_pose_dic)
4)顔ポーズリクエスト(左右同時に簡略化) 通常はこちら
pose_face(self, eyebrow_menue, eyebrow, eye_menue, eye, time,current_pose_dic)
5)顔ポーズリクエスト(左右個別)
pose_face_sp(self, eyebrow_menue, eyebrow_l, eyebrow_r, eye_menue, eye_r, eye_l, time,current_pose_dic)
6)口形状リクエスト
pose_mouth(self,mouth_menue, mouth_val, time, current_pose_dic)
7)頭ポーズリクエスト
pose_head(self,head_x,head_y,neck,time,current_pose_dic)
8)体ポーズリクエスト
pose_body(self, body_y, body_z, breathing, time, current_pose_dic)
9)感情ポーズリクエスト 顔全体を指定の感情に変える
pose_emotion(self, menue, time, current_pose_dic)
"happy":#喜
"angry":#怒
"sorrow":#哀
"relaxed":#楽
"smile":#微笑む
"laugh":#笑う
"surprised":#驚く
10)自動瞬き
mp_auto_eye_blink_start(self,start,end)
プロセスの開始及び停止
リクエスト→画像生成プロセス
start_mp_generater_process()
自動瞬きプロセス
mp_auto_eye_blink_start(self,start,end)
画像生成プロセス停止
mp_generater_process_terminate()
自動瞬きプロセス停止
mp_auto_eye_blink_teminate()
画像生成プロセスと自動瞬きプロセス同時停止
mp_all_proc_terminate()
生成画像取得
以下を定期的に呼び出します。スレッドやMPでメインのプログラムと分離すると便利です。
def get_image(self)
poser_generaterラッパー
ファイル名 poser_generater_v1_3.py
抽象化メソッドを提供するクラス
import numpy as np
import cv2
from PIL import Image
import argparse
from time import sleep
import time
import random
import multiprocessing
from multiprocessing import Process, Value, Manager
from poser_client_tkhmp_upmp_v1_3_class import TalkingHeadAnimefaceInterface
from tkh_up_scale import upscale
#PIL形式の画像を動画として表示 TEST用
def image_show(imge):
imge = np.array(imge)
imge = cv2.cvtColor(imge, cv2.COLOR_RGBA2BGRA)
cv2.imshow("Loaded image",imge)
cv2.waitKey(1)
#-----Dict形式
#{"eyebrow":{"menue":"happy","left":0.0,"right":0.0}, #menue: "troubled", "angry", "lowered", "raised", "happy", "serious"
# "eye":{"menue":"wink","left":0.0,"right":0.0}, #menue: "wink", "happy_wink", "surprised", "relaxed", "unimpressed", "raised_lower_eyelid"
# "iris_small":{"left":0.0,"right":0.0},
# "iris_rotation":{"x":0.0,"y":0.0},
# "mouth":{"menue":"aaa","val":0.0}, #menue: "aaa", "iii", "uuu", "eee", "ooo", "delta", "lowered_corner", "raised_corner", "smirk"
# "head":{"x":0.0,"y":0.0},
# "neck":0.0,
# "body":{"y":0.0,"z":0.0},
# "breathing":0.0,
# }
class TalkingHeadAnimefaceGenerater():
def __init__(self,Thi,img_number,user_id,mode,scale,fps):
self.img_number=img_number
self.user_id=user_id
self.mode=mode
self.scale=scale
self.fps=fps
self.pose_dic_org={"eyebrow":{"menue":"happy","left":0.0,"right":0.0},
"eye":{"menue":"wink","left":0.0,"right":0.0},
"iris_small":{"left":0.0,"right":0.0},
"iris_rotation":{"x":0.0,"y":0.0},
"mouth":{"menue":"aaa","val":0.0},
"head":{"x":0.0,"y":0.0},
"neck":0.0,
"body":{"y":0.0,"z":0.0},
"breathing":0.0,
}
self.current_poce_dic= self.pose_dic_org
#Thiの初期化
self.Thi=Thi
self.q_in_wink = None #ウインク、両目の瞬き
self.q_in_iris = None #
self.q_in_face = None #顔の感情
self.q_in_mouse = None #リップシンク
self.q_in_head = None #頭を動かす
self.q_in_body = None #体を動かす
self.q_in_pose = None #全Pose_Dicで動かす
self.queue_out_image = None #出力画像
self.out_image = np.zeros((512, 512, 3), dtype=np.uint8)#upscaleの最初で呼び出す初期画像、その後返送用のイメージバッファになる
self.global_out_image=self.out_image#_mp_generataerでアップスケース画像を保存
#start process
def start_mp_generater_process(self):
self.q_in_wink = multiprocessing.Queue() # 入力Queueを作成 ウインク
self.q_in_iris = multiprocessing.Queue() # 入力Queueを作成 瞳
self.q_in_face = multiprocessing.Queue() # 入力Queueを作成 顔の感情
self.q_in_mouth= multiprocessing.Queue() # 入力Queueを作成 リップシンク
self.q_in_head = multiprocessing.Queue() # 入力Queueを作成 頭を動かす
self.q_in_body = multiprocessing.Queue() # 入力Queueを作成 体を動かす
self.q_in_pose = multiprocessing.Queue() # 入力Queueを作成 #全Pose_Dicで動かす
self.queue_out_image = multiprocessing.Queue() # 出力Queueを作成
self.mp_generater_proc = multiprocessing.Process(target=self._mp_generataer,
args=(self.Thi,
self.pose_dic_org,
self.global_out_image,
self.queue_out_image,
self.img_number,
self.user_id,
self.mode,
self.scale,
self.fps,
self.q_in_wink,
self.q_in_iris,
self.q_in_face,
self.q_in_mouth,
self.q_in_head,
self.q_in_body,
self.q_in_pose,))
self.mp_generater_proc.start() #process開始
#self.mp_generater_proc.join()
#_mp_generatae(): 部位別POSEリクエストを確認してリクエストがあれば各部のPOSEを反映する
def _mp_generataer(self, Thi, pose_data_dic , global_out_image , out_image , img_number , user_id , mode , scale,fps,
q_in_wink,
q_in_iris,
q_in_face,
q_in_mouth,
q_in_head,
q_in_body,
q_in_pose,):
print("+++++ Start mp_generataer process")
pose_request=False
wink_request=False
iris_request=False
face_request=False
mouth_request=False
head_request=False
body_request=False
#lOOP開始 停止はプロセスのTERMINATE
while True:
start_time=time.time()
#ポーズリクエストQueueの監視と解析
if self.q_in_wink.empty()==False:#***
wink_data=self.q_in_wink.get()
wink_step_right=wink_data[1]
wink_step_left =wink_data[2]
wink_step_count=wink_data[0]
wink_step_count_p=wink_step_count
wink_step_count_n=wink_step_count
wink_request=True
pose_request=True
print("+++++ wink_data=",wink_data)
elif self.q_in_iris.empty()==False:#***
iris_data=self.q_in_iris.get()
iris_small_step_left=iris_data[1]
iris_small_step_right =iris_data[2]
iris_rotation_step_x =iris_data[3]
iris_rotation_step_y =iris_data[4]
iris_step_count=iris_data[0]
iris_request=True
pose_request=True
print("+++++ iris_data=",iris_data)
elif self.q_in_face.empty()==False:#***
face_data=self.q_in_face.get()
eyebrow_step_right=face_data[1]
eyebrow_step_left =face_data[2]
eyebrow_menue =face_data[3]
face_eye_step_right=face_data[4]
face_eye_step_left =face_data[5]
face_eye_menue =face_data[6]
face_step_count =face_data[0]
face_request=True
pose_request=True
print("+++++ face_data=",face_data)
elif self.q_in_mouth.empty()==False:#***
mouth_data=self.q_in_mouth.get()
mouth_step=mouth_data[2]
mouth_menue=mouth_data[1]
mouth_step_count=mouth_data[0]
mouth_request=True
pose_request=True
print("+++++ mouth_data=",mouth_data)
elif self.q_in_head.empty()==False:#***
head_data=self.q_in_head.get()
head_step_x=head_data[1]
head_step_y=head_data[2]
neck_step=head_data[3]
head_step_count=head_data[0]
head_request=True
pose_request=True
print("+++++ head_data",head_data)
elif self.q_in_body.empty()==False:#***
body_data=self.q_in_body.get()
body_step_y=body_data[1]
body_step_z=body_data[2]
breath_step=body_data[3]
body_step_count=body_data[0]
body_request=True
pose_request=True
print("+++++ body_data",body_data)
elif self.q_in_pose.empty()==False:# (Pose Dic全体が送られて来る)=>改め、生成画像を取得する役目に
pose_data=self.q_in_pose.get()
pose_request=True #他のリクエストがなければ画像と最新pose_dataを送信する
#リクエストがあればポーズデータをStep数とStep値で更新していく。if文なので各々の変化も同時に更新できる
if pose_request:
if wink_request:#*** wink(eye)
pose_data_dic["eye"]["menue"]="wink"
if wink_step_count_p>0:
pose_data_dic["eye"]["right"] +=wink_step_right
pose_data_dic["eye"]["left"] +=wink_step_left
wink_step_count_p -=1
elif wink_step_count_n>0:
pose_data_dic["eye"]["right"]-=wink_step_right
pose_data_dic["eye"]["left"] -=wink_step_left
wink_step_count_n -=1
else:
wink_request=False
if iris_request:#*** iris
if iris_step_count>0:
pose_data_dic["iris_small"]["right"] +=iris_small_step_right
pose_data_dic["iris_small"]["left"] +=iris_small_step_left
pose_data_dic["iris_rotation"]["x"] +=iris_rotation_step_x
pose_data_dic["iris_rotation"]["y"] +=iris_rotation_step_y
iris_step_count -=1
else:
iris_request=False
if face_request:#*** face (eyebrow_menue + eye)
pose_data_dic["eyebrow"]["menue"] =eyebrow_menue
pose_data_dic["eye"]["menue"]=face_eye_menue
if face_step_count>0:
pose_data_dic["eyebrow"]["right"]+=eyebrow_step_right
pose_data_dic["eyebrow"]["left"] +=eyebrow_step_left
pose_data_dic["eye"]["right"] +=face_eye_step_right
pose_data_dic["eye"]["left"] +=face_eye_step_left
face_step_count -=1
else:
face_request=False
if mouth_request:#*** mouth
pose_data_dic["mouth"]["menue"]=mouth_menue
if mouth_step_count>0:
pose_data_dic["mouth"]["val"] +=mouth_step
mouth_step_count -=1
else:
mouth_request=False
if head_request:#*** head (head + neck)
if head_step_count>0:
pose_data_dic["head"]["x"] +=head_step_x
pose_data_dic["head"]["y"] +=head_step_y
pose_data_dic["neck"] +=neck_step
head_step_count -=1
else:
head_request=False
if body_request:#*** body (body + breath
if body_step_count>0:
pose_data_dic["body"]["y"] +=body_step_y
pose_data_dic["body"]["z"] +=body_step_z
pose_data_dic["breathing"] +=breath_step
body_step_count -=1
else:
body_request=False
#新しいポーズデータができたので画像の生成を依頼する
out_image,result=Thi.mp_dic2image_frame(global_out_image, pose_data_dic ,img_number, user_id, mode, scale, 0)
#生成が間に合わなかった場合は画像をqueueに送信しない
if result:
if self.queue_out_image.empty():
send_data=[out_image , pose_data_dic]
self.queue_out_image.put(send_data)
print("mp_generataer : remain time to frame rate=",1/self.fps - (time.time()-start_time))
if (1/self.fps - (time.time()-start_time))>0:
sleep(1/self.fps - (time.time()-start_time))
else:
print("mp_generatae Remain time is minus")
pose_request=False
sleep(0.005)
#mp_generater_processプロセス停止関数--terminate
def mp_generater_process_terminate(self):
while not self.queue_out_image.empty():
self.queue_out_image.get_nowait()
while not self.q_in_pose.empty():
self.q_in_pose.get_nowait()
self.mp_generater_proc.terminate()#サブプロセスの終了
print("mp_generataer process terminated")
def mp_auto_eye_blink_start(self,start,end):
self.mp_auto_eye_blink_proc = multiprocessing.Process(target=self._mp_auto_eye_blink,args=(start,end,self.pose_dic_org))
self.mp_auto_eye_blink_proc.start() #process開始
def _mp_auto_eye_blink(self,start,end,pose_data_dic):
print("++++++ Start mp_auto_eye_blink")
while True:
sleep(random.randint(start, end))
print(pose_data_dic)
self.pose_wink("b", 0.1, pose_data_dic)
def mp_auto_eye_blink_teminate(self):
self.mp_auto_eye_blink_proc.terminate()
# wink(瞬きも)ポーズリクエスト
def pose_wink(self,l_r, time,current_pose_dic):
if self.q_in_wink.empty():
step_count=int((time/(1/self.fps))/2)
if l_r=="l":
if self.q_in_wink.empty():
eye_left=(1-current_pose_dic["eye"]["left"])/step_count
send_data=[step_count,0.0,eye_left]
self.q_in_wink.put(send_data)
elif l_r=="r":
if self.q_in_wink.empty():
eye_right=(1-current_pose_dic["eye"]["right"])/step_count
send_data=[step_count,eye_right,0.0]
self.q_in_wink.put(send_data)
elif l_r=="b":
if self.q_in_wink.empty():
eye_left=(1-current_pose_dic["eye"]["left"])/step_count
eye_right=(1-current_pose_dic["eye"]["right"])/step_count
send_data=[step_count,eye_right,eye_left]
self.q_in_wink.put(send_data)
print("===============pose_wink: l_r=",l_r," send_data=",send_data)
# 瞳ポーズリクエスト(左右同時に簡略化) 通常はこちら
def pose_iris(self, iris_small, iris_rotation, time,current_pose_dic):
self.pose_iris_sp(iris_small, iris_small, iris_rotation, iris_rotation,time,current_pose_dic)
# 瞳ポーズリクエスト(左右個別)
def pose_iris_sp(self, iris_l, iris_r, iris_x,iris_y,time,current_pose_dic):
if self.q_in_iris.empty():
step_count=int(time/(1/self.fps))
iris_l_step = (iris_l-current_pose_dic["iris_small"]["left"])/step_count
iris_r_step = (iris_r-current_pose_dic["iris_small"]["right"])/step_count
iris_x_step = (iris_x-current_pose_dic["iris_rotation"]["x"])/step_count
iris_y_step = (iris_y-current_pose_dic["iris_rotation"]["y"])/step_count
send_data=[step_count,iris_l_step ,iris_r_step ,iris_x_step, iris_y_step]
self.q_in_iris.put(send_data)
print("===============pose_iris: send_data=",send_data)
# 顔ポーズリクエスト(左右同時に簡略化) 通常はこちら
def pose_face(self, eyebrow_menue, eyebrow, eye_menue, eye, time,current_pose_dic):
self.pose_face_sp(eyebrow_menue, eyebrow, eyebrow, eye_menue, eye, eye, time,current_pose_dic)
# 顔ポーズリクエスト(左右個別)
def pose_face_sp(self, eyebrow_menue, eyebrow_l, eyebrow_r, eye_menue, eye_r, eye_l, time,current_pose_dic):
if self.q_in_face.empty():
step_count=int(time/(1/self.fps))
eyebrow_l_step = (eyebrow_l - current_pose_dic["eyebrow"]["left"])/step_count
eyebrow_r_step = (eyebrow_r - current_pose_dic["eyebrow"]["right"])/step_count
eye_l_step = (eye_l - current_pose_dic["eye"]["left"])/step_count
eye_r_step = (eye_r - current_pose_dic["eye"]["right"])/step_count
send_data=[step_count,eyebrow_l_step ,eyebrow_r_step ,eyebrow_menue, eye_r_step, eye_l_step, eye_menue]
self.q_in_face.put(send_data)
print("===============pose_face: send_data=",send_data)
# 口形状リクエスト
def pose_mouth(self,mouth_menue, mouth_val, time, current_pose_dic):
if self.q_in_mouth.empty():
step_count=int(time/(1/self.fps))
mouth_val_step = (mouth_val-current_pose_dic["mouth"]["val"])/step_count
send_data=[step_count, mouth_menue ,mouth_val_step]
self.q_in_mouth.put(send_data)
print("===============pose_mouth: send_data=",send_data)
# 頭ポーズリクエスト
def pose_head(self,head_x,head_y,neck,time,current_pose_dic):
if self.q_in_head.empty():
step_count=int(time/(1/self.fps))
head_x_step = (head_x-current_pose_dic["head"]["x"])/step_count
head_y_step = (head_y-current_pose_dic["head"]["y"])/step_count
neck_step = (neck-current_pose_dic["neck"])/step_count
send_data=[step_count,head_x_step ,head_y_step ,neck_step]
self.q_in_head.put(send_data)
print("===============pose_head: send_data=",send_data)
# 体ポーズリクエスト
def pose_body(self, body_y, body_z, breathing, time, current_pose_dic):
if self.q_in_body.empty():
step_count=int(time/(1/self.fps))
body_y_step = (body_y-current_pose_dic["body"]["y"])/step_count
body_z_step = (body_z-current_pose_dic["body"]["z"])/step_count
breathi_step = (breathing-current_pose_dic["breathing"])/step_count
send_data=[step_count,body_y_step ,body_z_step ,breathi_step]
self.q_in_body.put(send_data)
print("===============pose_body: send_data=",send_data)
# 感情ポーズリクエスト "happy":#喜 "angry":#怒 "sorrow":#哀 relaxed":#楽 "smile":#微笑む "laugh":#笑う "surprised":#驚く
def pose_emotion(self, menue, time, current_pose_dic):
if menue=="happy":#喜
self.pose_face("happy", 1.0, "happy_wink", 1.0, time, current_pose_dic)
self.pose_mouth("iii", 1.0, time, current_pose_dic)
elif menue=="angry":#怒
self.pose_face("angry", 1.0, "raised_lower_eyelid", 1.0, time, current_pose_dic)
self.pose_mouth("uuu", 1.0, time, current_pose_dic)
elif menue=="sorrow":#哀
self.pose_face("troubled", 1.0, "unimpressed", 1.0, time, current_pose_dic)
self.pose_mouth("ooo", 1.0, time, current_pose_dic)
elif menue=="relaxed":#楽
self.pose_face("happy", 1.0, "relaxed", 1.0, time, current_pose_dic)
self.pose_mouth("aaa", 0.0, time, current_pose_dic)
elif menue=="smile":#微笑む
self.pose_face("happy", 1.0, "relaxed", 1.0, time, current_pose_dic)
self.pose_mouth("aaa", 0.0, time, current_pose_dic)
elif menue=="laugh":#笑う
self.pose_face("happy", 1.0, "wink", 0.0, time, current_pose_dic)
self.pose_mouth("aaa", 1.0, time, current_pose_dic)
elif menue=="surprised":#驚く
self.pose_face("lowered", 1.0, "surprised", 1.0, time, current_pose_dic)
self.pose_mouth("aaa", 1.0, time, current_pose_dic)
else:
print("Emotion Error")
# 画像の取得
def get_image(self):#as Get image
if self.q_in_pose.empty():
self.q_in_pose.put("get_image") #送るデータは何でも良い
if self.queue_out_image.empty()==False:
recive_data = self.queue_out_image.get()
self.out_image = recive_data[0] #_mp_generataerから送られてきた生成画像
self.current_poce_dic = recive_data[1]
return self.out_image ,self.current_poce_dic
#全プロセス停止
def mp_all_proc_terminate(self):
self.mp_generater_process_terminate()
self.mp_auto_eye_blink_teminate()
テストコード
3パートに別れています。口の変化は便宜上リスト内のポースにしたがって定期的に変わるようにしていますが、本来はリップシンク用なのでttsから随時呼び出される使い方をします。他のメソッドも随時必要な時に呼びさせば動いてくれます。以下のコードではfor文で順次呼び出すような方法でテストしました。
import numpy as np
import cv2
from PIL import Image
import argparse
from time import sleep
import time
from poser_client_tkhmp_upmp_v1_3_class import TalkingHeadAnimefaceInterface
from poser_generater_v1_3 import TalkingHeadAnimefaceGenerater
def main():
parser = argparse.ArgumentParser(description='Talking Head')
parser.add_argument('--filename','-i', default='000002.png', type=str)
parser.add_argument('--test', default=0, type=int)
parser.add_argument('--thk', default='http://0.0.0.0:8001', type=str)
parser.add_argument('--esr', default='http://0.0.0.0:8008', type=str)
args = parser.parse_args()
test =args.test
filename =args.filename
user_id=0 #便宜上設定している。0~20の範囲。必ず設定すること
tkh_url=args.thk
esr_url=args.esr + "/resr_upscal/"
#Thiの初期化
Thi=TalkingHeadAnimefaceInterface(tkh_url) # tkhのホスト 、アップスケールのURLはプロセス開始で指定
#pose_dic_orgの設定。サーバからもらう
pose_dic_org = Thi.get_init_dic()
#アップスケールとtkhプロセスの開始
Thi.create_mp_upscale(esr_url)
Thi.create_mp_tkh()
#サンプル 1 inference_dic() poseはDICT形式で直接サーバを呼ぶ イメージは事前ロード DICT形式で必要な部分のみ選んで連続変化させる
if test==1:
fps=40
#mode="breastup" # "breastup" , "waistup" , upperbody" , "full"
#mode="waistup" # "breastup" , "waistup" , upperbody" , "full"
mode=[55,155,200,202] #[top,left,hight,whith]
scale=2 # 2/4/8
div_count=300
input_image = Image.open(filename)
imge = np.array(input_image)
imge = cv2.cvtColor(imge, cv2.COLOR_RGBA2BGRA)
result_out_image = imge
cv2.imshow("image",imge)
cv2.waitKey() #ここで一旦止まり、キー入力で再開する
img_number=Thi.load_img(input_image,user_id) # 画像のアップロード
pose_dic_org={"eyebrow":{"menue":"happy","left":0.0,"right":0.0},
"eye":{"menue":"wink","left":0.0,"right":0.0},
"iris_small":{"left":0.0,"right":0.0},
"iris_rotation":{"x":0.0,"y":0.0},
"mouth":{"menue":"aaa","val":0.0},
"head":{"x":0.0,"y":0.0},
"neck":0.0,
"body":{"y":0.0,"z":0.0},
"breathing":0.0,
}
Tkg=TalkingHeadAnimefaceGenerater(Thi,img_number,user_id,mode,scale,fps)
#ポーズデータ生成プロセスのスタート
Tkg.start_mp_generater_process()
#pose_dic=pose_dic_org #Pose 初期値
current_pose_list=[]
move_time=div_count/2*(1/fps)
current_pose_dic=pose_dic_org #Pose 初期値
#Head pose 動作開始
Tkg.pose_head(0.0, 3.0, 3.0, move_time, current_pose_dic)#head_x,head_y,neck,time,current_pose_dic
#Head body 動作開始
Tkg.pose_body(3.0, 3.0, 3.0, move_time, current_pose_dic)#body_y, body_z, breathing,time,current_pose_dic
Tkg.mp_auto_eye_blink_start(1,2)
mouth_list=["aaa","iii","uuu","eee","ooo","aaa"]
mouth_pointer=0
for i in range(int(div_count/2)):
start_time=time.time()
# mouthe pose
mouthe_menue = mouth_list[mouth_pointer]
if (i==50 or i==60 or i==70 or i==80 or i==100):
mouth_menue = mouth_list[mouth_pointer]
Tkg.pose_mouth(mouth_menue, 1.0, 0.1, current_pose_dic)
mouth_pointer +=1
if (i==130):
Tkg.pose_mouth("aaa", 0.0, 0.1, current_pose_dic)
# mabataki pose
if (i==20 or i==50):
Tkg.pose_wink("b", 0.15,current_pose_dic)#l_r,time
# wink pose
if (i==10 or i==30):
Tkg.pose_wink("l", 0.2,current_pose_dic)#l_r,time
if (i==65):
Tkg.pose_wink("r", 0.2,current_pose_dic)#l_r,time
# iris pose
if (i==5 or i==75):
Tkg.pose_iris(1.0, 0.0, 0.1,current_pose_dic)#small,rotation,time
if (i==25 or i==85):
Tkg.pose_iris(0.0, 0.0, 0.15,current_pose_dic)#small,rotation,time
if (i==140):
Tkg.pose_face("happy", 0.0, "happy_wink", 0.0, 0.5,current_pose_dic)#happy :eyebrow_menue, eyebrow, eye_menue, eye, time,current_pose_dic
#画像の取得
result_out_image, current_pose_dic = Tkg.get_image()
cv2.imshow("Loaded image",result_out_image)
cv2.waitKey(1)
#cv2.imwrite("image/image"+str(i)+".jpg",result_out_image)
print("1/fps - (time.time()-start_time)=",1/fps - (time.time()-start_time))
if (1/fps - (time.time()-start_time))>0:
sleep(1/fps - (time.time()-start_time))
else:
print("Remain time is minus")
print("Genaration time=",(time.time()-start_time)*1000,"mS")
#Head pose 動作開始
Tkg.pose_head(0.0, -3.0, 0.0, move_time, current_pose_dic)#head_x,head_y,neck,time,current_pose_dic
# body pose 動作開始
Tkg.pose_body(-6.0, -3.0, -3.0, move_time, current_pose_dic)#body_y, body_z, breathing,time,current_pose_dic
for i in range(int(div_count/2)):
start_time=time.time()
#Emotion 指定 → "happy" #喜 "angry" #怒 "sorrow" #哀 "relaxed" #楽 "smile" #微笑む "laugh" #笑う "surprised" #驚く
if i==20:
Tkg.pose_emotion("happy",0.5, current_pose_dic)
if i==60:
Tkg.pose_emotion("angry", 0.5, current_pose_dic)
if i==100:
Tkg.pose_emotion("sorrow", 0.5, current_pose_dic)
if i==140:
Tkg.pose_emotion("relaxed", 0.5, current_pose_dic)
#画像の取得
result_out_image, current_pose_dic = Tkg.get_image()
cv2.imshow("Loaded image",result_out_image)
cv2.waitKey(1)
#cv2.imwrite("image/image2"+str(i)+".jpg",result_out_image)
print("1/fps - (time.time()-start_time)=",1/fps - (time.time()-start_time))
if (1/fps - (time.time()-start_time))>0:
sleep(1/fps - (time.time()-start_time))
else:
print("Remain time is minus")
print("Genaration time=",(time.time()-start_time)*1000,"mS")
#Head pose 動作開始
Tkg.pose_head(0.0, 0.0, 0.0, move_time, current_pose_dic)#head_x,head_y,neck,time,current_pose_dic
# body pose 動作開始
Tkg.pose_body(0.0, 0.0, 0.0, move_time, current_pose_dic)#body_y, body_z, breathing,time,current_pose_dic
#Tkg.mp_auto_eye_blink_start(1,3)
for i in range(int(div_count/2)):
start_time=time.time()
#Emotion 指定 → "happy" #喜 "angry" #怒 "sorrow" #哀 "relaxed" #楽 "smile" #微笑む "laugh" #笑う "surprised" #驚く
if i==20:
Tkg.pose_emotion("laugh", 0.5, current_pose_dic)
if i==60:
Tkg.pose_emotion("surprised", 0.2, current_pose_dic)
if i==800:
Tkg.pose_emotion("smile", 0.5, current_pose_dic)
if i==100:
Tkg.pose_face("happy", 0.0, "happy_wink", 0.0, 0.5,current_pose_dic)#happy :eyebrow_menue, eyebrow, eye_menue, eye, time,current_pose_dic
Tkg.pose_mouth("aaa", 0.0, 0.5, current_pose_dic)
#画像の取得
result_out_image, current_pose_dic = Tkg.get_image()
cv2.imshow("Loaded image",result_out_image)
cv2.waitKey(1)
#cv2.imwrite("image/image3"+str(i)+".jpg",result_out_image)
print("1/fps - (time.time()-start_time)=",1/fps - (time.time()-start_time))
if (1/fps - (time.time()-start_time))>0:
sleep(1/fps - (time.time()-start_time))
else:
print("Remain time is minus")
print("Genaration time=",(time.time()-start_time)*1000,"mS")
cv2.imshow("Loaded image",result_out_image)
cv2.waitKey(5)
cv2.waitKey(1000)
#サブプロセスの終了
Thi.up_scale_proc_terminate()
Thi.tkh_proc_terminate()
#Tkg.mp_generater_process_terminate()
#Tkg.mp_auto_eye_blink_teminate()
Tkg.mp_all_proc_terminate()
sleep(5)
print("end of test")
if __name__ == "__main__":
main()