項目の動割当

Data: lwk_field_name(30) type c.

 

Field-symbols:<fs_field> type any.

 

Lwk_field_name = XXXXXX.

Assign (lwk_field_name) to <fs_field>.

If <fs_field> is assigned.

       ……

Endif.

now i will show you my code # ################################################################ # 手話メイン処理 # # ################################################################ # ---------------------------------------------------------------- # import # ---------------------------------------------------------------- import os os.environ["OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS"] = "0" # カメラ立ち上がりが遅い問題へ対策 import cv2 # pip install opencv-python import numpy as np import threading from collections import deque from logging import NullHandler import SignLanguageDebug as sld import SignLanguageGUI as slg import SignLanguageClassifier as slc import SignLanguagePreview as slp import SignLanguageSetting as sls from SignLanguageCommon import Pose from SignLanguageCommon import Hand from SignLanguageCommon import Train from SignLanguageCommon import Face from SignLanguageCommon import Mouth WinParam = slg.GetWindowParam() play_flg:bool = False # メイン処理スレッド起動有無 hol_thread:threading.Thread = None is_shot:bool = False # 撮影可否(キューに積む判定) tm = NullHandler # ---------------------------------------------------------------- # function # ---------------------------------------------------------------- ## # メイン処理スレッド # 入力映像を取り込んで手話判定し、結果を表示する def HolisticThread(error_func): global WinParam global play_flg global is_shot global tm WinParam = slg.GetWindowParam() rec_frame_num = sls.GetRecordFrameNum() # 記録するフレーム数(約1秒分) cap_width, cap_height = sls.GetCameraResolution() # 入力 (横幅, 縦幅) disp_width, disp_height = sls.GetDisplayResolution() # 出力 (横幅, 縦幅) LoadModel:str = "" # 学習済みモデル有無 confidence:float = sls.GetSignConfidence() # 手話判定閾値 pre_que_count = sls.GetPreQueCount() # 手話開始直前に溜めるフレーム数 lips_close_count = sls.GetLipsCloseCount() # 口が閉じていると判断するフレーム数 cap = cv2.VideoCapture(WinParam["CAM_ID"]) if not cap.isOpened(): print("Failed to open camera") error_func() else: cap.set(cv2.CAP_PROP_FRAME_WIDTH, cap_width) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, cap_height) pos_que = deque(maxlen=rec_frame_num) # 手話データキュー sign = "" per = 0.0 pre_que = deque(maxlen=pre_que_count) # 手話開始直前フレームキュー lips_close_range = deque([True]*lips_close_count, maxlen=lips_close_count) # 口が閉じていると判断するまで期間 # FPS開始 sld.FpsStart() # ショットタイマー開始 tm = threading.Timer(1/rec_frame_num, ShotCb) tm.start() # 学習済みモデル読み込み LoadModel = slc.LoadSignLanguageModel() # メインループ while play_flg == True: success, img = cap.read() if not success: print("Failed to capture camera") error_func() break cap_height, cap_width, _ = img.shape # キャプチャサイズを取り直す w_offset = int((cap_width-cap_height)/2) img = img[0:cap_height, w_offset:w_offset+cap_height] # 縦幅に合わせて正方形クロッピング img = cv2.flip(img, 1) # カメラ画像場合は左右反転 results = sls.holistic.process(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # 手話判定対象となる点取得 ret, pos, area_width, upp_l, low_r = GetTargetPosition(results) # 手話区切り目安となる点取得 lips_pos, lips_close, lips_dist, mouth_ratio = GetMouthPosition(results) # 手話判定領域が取得できたときに処理をする if ret == "OK": # デバッグ用情報描画 if WinParam["DBG_MODE"] == "全表示": sld.DrawAllInfo(img, results) elif WinParam["DBG_MODE"] == "対象み表示": sld.DrawTargetInfo(img, pos, lips_pos, cap_height) # 手話モード if WinParam["CAM_MODE"] == "Sign": if len(pos_que) > 0: cv2.putText(img, "{}".format(len(pos_que)), np.uint16((upp_l * cap_height - 10).tolist()), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,255), 2) cv2.rectangle(img, np.uint16((upp_l * cap_height).tolist()), np.uint16((low_r * cap_height).tolist()), (0, 0, 255), 2) else: cv2.rectangle(img, np.uint16((upp_l * cap_height).tolist()), np.uint16((low_r * cap_height).tolist()), (0, 255, 0), 1) # 学習モード else: if WinParam["REC_START"] == "Recording": cv2.rectangle(img, np.uint16((upp_l * cap_height).tolist()), np.uint16((low_r * cap_height).tolist()), (0, 0, 255), 2) else: cv2.rectangle(img, np.uint16((upp_l * cap_height).tolist()), np.uint16((low_r * cap_height).tolist()), (0, 255, 0), 1) if is_shot == True: is_shot = False # データ正規化 pos = pos - upp_l # 領域左上を(0,0)にする pos = pos / area_width # 領域幅でる li = (pos.flatten()).tolist() # 一次元配列に変換 li = [0.0 if i < 0.0 else i for i in li] # 0.0以下を0.0にする li = [1.0 if i > 1.0 else i for i in li] # 1.0以上を1.0にする pos_que.append(li) # キューに登録 if WinParam["CAM_MODE"] == "Sign": # -------------------------------------------- # 手話モード # -------------------------------------------- lips_close_range.append(lips_close) if lips_close_range.count(True) == lips_close_count: # 一定フレーム 口が閉じていたら手話対象としない pos_que.clear() pre_que.append(li) # 閉じてる間フレームを保持 else: # 口が開いたら直前数フレームを挿入する pre_que_num = len(pre_que) if pre_que_num > 0: for pi in range(pre_que_num): pos_que.appendleft(pre_que[pre_que_num - 1 - pi]) pre_que.clear() if LoadModel == "OK" and len(pos_que) == rec_frame_num: in_data = np.array([list(pos_que)], dtype=np.float32) result = slc.PredictSignLanguage(in_data) slg.SetPredictResult(result) if np.argmax(result) != 0 and np.amax(result) >= confidence: sign = slg.GetSign(np.argmax(result)) per = np.amax(result)*100 if sls.GetPreviewEnableSign() is True: slp.StartPreviewByList(list(pos_que), True) pos_que.clear() else: # -------------------------------------------- # 学習モード # -------------------------------------------- sign = "" per = 0.0 if WinParam["REC_START"] == "Start": pos_que.clear() WinParam["REC_START"] = "Recording" elif WinParam["REC_START"] == "Recording" and len(pos_que) == rec_frame_num: filename_list = slc.SaveTrainingDataFile(WinParam["LABEL_ID"], list(pos_que), rec_frame_num) if sls.GetPreviewEnableTrain() is True: # 学習データプレビュー slp.StartPreviewByFile(filename_list[0], True) # 学習データ保存確認 slg.ConfirmFileSave(filename_list) # 学習データ保存完了通知 slg.NotifyFileSaveComp(WinParam["LABEL_ID"]) WinParam["REC_START"] = "Stop" slg.SetStatusText("") WinParam["REC_NUM"] -= 1 if WinParam["REC_NUM"] > 0: slg.CallCountDown() # 手話判定領域が取得できない場合に表示をクリアする else: sign = "" per = 0.0 if sign != "": sld.DrawText( img, sign + " {:.2f}%".format(per), org_y=cap_height-30, color=(255,255,255), bg = True, bgcolor=(0,0,0) ) elif ret == "ToCenter": # 画面中央へ移動することを誘導 sld.DrawText(img, "画面中央に移動してください") elif ret == "StepBack": # 後ろに下がることを誘導 sld.DrawText(img, "後ろに下がってください") # FPS表示 sld.FpsOutput(img) # lips_dist 表示 sld.mouthDistOutput(img, lips_dist, mouth_ratio, lips_close) # 画像表示 img = cv2.resize(img, (disp_width, disp_height)) # 出力サイズにリサイズ cv2.imshow("Sign Language", img) cv2.waitKey(1) cap.release() cv2.destroyAllWindows() # ショットタイマー破棄 tm.cancel() del tm tm = NullHandler ## # 手話判定対象となる点取得 # ポーズ、左右手情報から手話判定対象となる点を取得し、リスト化する def GetTargetPosition(results:type): pos:np.ndarray = np.empty((0,2)) # 手話判定対象となる点群 upp_l:np.ndarray = np.empty((0,2)) # 手話判定領域左上座標 low_r:np.ndarray = np.empty((0,2)) # 手話判定領域右下座標 area_width:np.float32 = 1.0 w_times:np.float32 = 3.0 # 肩幅何倍を手話判定領域にするか # ---------------- # ポーズ if results.pose_landmarks: p_lm = results.pose_landmarks.landmark # 鼻、両目、両肩、両腕 を取得 pose_list = [ Pose.NOSE, Pose.L_EYE, Pose.R_EYE, Pose.L_SHOULDER, Pose.R_SHOULDER, Pose.L_ELBOW, Pose.R_ELBOW, ] for i in pose_list: pos = np.append(pos, [[p_lm[i].x, p_lm[i].y]], axis=0) # 両肩中心を追加 pos = np.append(pos, [(pos[Train.L_SHOULDER] + pos[Train.R_SHOULDER])/2], axis=0) # 手話判定領域を求める area_width = np.linalg.norm(pos[Train.L_SHOULDER] - pos[Train.R_SHOULDER]) * w_times upp_l = pos[Train.C_SHOULDER] - area_width/2 low_r = pos[Train.C_SHOULDER] + area_width/2 # 領域がキャプチャ領域内に収まっているか if upp_l[0] < 0.0 or low_r[0] > 1.0: # 左寄りor右寄り return "ToCenter", pos, area_width, upp_l, low_r elif upp_l[1] < 0.0 or low_r[1] > 1.0: # 上寄りor下寄り return "StepBack", pos, area_width, upp_l, low_r else: # 取得できなかったときは左右寄りとする return "ToCenter", pos, area_width, upp_l, low_r # ---------------- # 左手 if results.left_hand_landmarks: # 左手位置情報を全て取得 for h_id, h_lm in enumerate(results.left_hand_landmarks.landmark): pos = np.append(pos, [[h_lm.x, h_lm.y]], axis=0) else: # 取得できなかったときは -1にする for index in range(len(Hand)): pos = np.append(pos, [[-1.0, -1.0]], axis=0) # ---------------- # 右手 if results.right_hand_landmarks: # 右手位置情報を全て取得 for h_id, h_lm in enumerate(results.right_hand_landmarks.landmark): pos = np.append(pos, [[h_lm.x, h_lm.y]], axis=0) else: # 取得できなかったときは -1にする for index in range(len(Hand)): pos = np.append(pos, [[-1.0, -1.0]], axis=0) return "OK", pos, area_width, upp_l, low_r def GetMouthPosition(results:type): pos:np.ndarray = np.empty((0,2)) # 手話区切り判定に使用する点群 lips_dist:np.float32 = 0.0 # 上唇と下唇距離 lips_side_dist:np.float32 = 0.0 # 左右唇距離 mouth_ratio :np.float32 = 0.0 # 口縦横合(横幅÷縦幅) lips_close:bool = True # 口が閉じてるかどうか # ---------------- # 唇 if results.face_landmarks: f_lm = results.face_landmarks.landmark face_list = [ Face.UPPER_LIP, Face.UNDER_LIP, Face.L_SIDE_LIP, Face.R_SIDE_LIP, ] for i in face_list: pos = np.append(pos, [[f_lm[i].x, f_lm[i].y]], axis=0) # 上唇と下唇距離を求める lips_dist = np.linalg.norm(pos[Mouth.UPPER_LIP] - pos[Mouth.UNDER_LIP]) # 左右唇距離を求める lips_side_dist = np.linalg.norm(pos[Mouth.L_SIDE_LIP] - pos[Mouth.R_SIDE_LIP]) if lips_dist <= 0.0: lips_dist = sls.GetMouthOpenThd() mouth_ratio = lips_side_dist / lips_dist # 口開閉判定 if lips_dist <= sls.GetMouthOpenThd() and mouth_ratio >= sls.GetMouthOpenRatio(): lips_close = True else: lips_close = False else: # 取得できなかったときは 口を閉じてるとする lips_dist = 0.0 mouth_ratio = 0.0 lips_close = True # 取得できなかったときは -1にする for index in range(len(Mouth)): pos = np.append(pos, [[-1.0, -1.0]], axis=0) return pos, lips_close, lips_dist, mouth_ratio ## # メイン処理スレッド開始 def StartSignLanguage(error_func): global hol_thread global play_flg hol_thread = threading.Thread(target=HolisticThread, args=[error_func,], daemon=True) play_flg = True hol_thread.start() ## # メイン処理スレッド終了 def StopSignLanguage(): global hol_thread global play_flg play_flg = False hol_thread.join() ## # パラメータ更新 def UpdateParam(param): global WinParam print(param) WinParam = param ## # ショットタイマー # 記録するフレーム数(fps)調整タイマー def ShotCb(): global is_shot global tm tm.cancel() del tm tm = NullHandler is_shot = True rec_frame_num = sls.GetRecordFrameNum() tm = threading.Timer(1/rec_frame_num, ShotCb) tm.start() ## # メイン処理 # 必要なスレッド立ち上げとGUI作成 if __name__ == "__main__": # プロセス開始 slp.StartPreviewProcess() slg.CreateMainWindow( StartFunc = StartSignLanguage, StopFunc = StopSignLanguage, UpdateParam = UpdateParam ) # プロセス終了 slp.StopPreviewProcess()
09-03
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值