見出し画像

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()