現在、Tobii Pro グラス3で計測した視線計測結果のデータを示したgazedata.txt(これはgazedataに拡張子.txtを付けたもの)とその際に見ていた動画scenevideo.mp4(視点が含まれていないもの)を用いてscenevideo.mp4上にgazedataで示した座標をプロットしたいと思っています。
gazedata.txtは以下のようになっており、各行のタイムスタンプ、視点のX座標、Y座標の3項目をその下のプログラムで取り出すようにしています。
{"type":"gaze","timestamp":0.005122,"data":{"gaze2d":[0.4602403422245705,0.63518018245494501],"gaze3d":[47.463591971014097,-80.874777137044418,605.30066418125637],"eyeleft":{},"eyeright":{"gazeorigin":[-32.240116992256553,-8.6559079988472227,-24.281042030626143],"gazedirection":[0.12479683703612067,-0.11307981926130367,0.98571735499665958],"pupildiameter":3.6292469501495361}}} {"type":"gaze","timestamp":0.015189,"data":{"gaze2d":[0.46085044431863087,0.64542006373782357],"gaze3d":[45.604816280414603,-86.335128904916019,593.24112124943133],"eyeleft":{"gazeorigin":[32.830473069607699,-8.7684774873996272,-26.483972087054845],"gazedirection":[0.02045490660481088,-0.12417637690129764,0.99204930533489888],"pupildiameter":3.4933187961578369},"eyeright":{}}}
そこで、以下の75行目のcircleで視点の位置に円を描くことで視点を示すため、画面の縦横のサイズである1920と1080にgazedataで0~1で示される座標を掛け、intにしたところ、
res = cv2.circle(res, int(gx[n]*1920),int(gy[n]*1080)), 8, (0, 0, 255), thickness=5)IndexError: listout of range
と出ました。ここで、ちゃんと視点の位置でプロットできるようにするにはどうすればよいかお教え頂きたいです。
また、文末に記載しているように、プログラム内で採取したタイムスタンプとgazedata内のタイムスタンプが異なるため、プロットするタイミングをどのように行うべきかお教えいただきたいです。
python
1# coding: utf-8 2import cv2 3import numpy as np 4import time 5import get_gazedata 6import re 7#from numba import jit 8device = "scenevideo.mp4" 9#@jit 10 11 12def get_timestamps(video_path): 13 cap = cv2.VideoCapture(video_path) 14 timestamps = [cap.get(cv2.CAP_PROP_POS_MSEC)] 15 while cap.isOpened(): 16 frame_exists, curr_frame = cap.read() 17 if not frame_exists: 18 break 19 timestamp = cap.get(cv2.CAP_PROP_POS_MSEC) 20 timestamps.append(timestamp) 21 cap.release() 22 return timestamps 23 24 25def main(): 26 #変数 27 gt = [] 28 gx = [] 29 gy = [] 30 31#movie 32 global device 33 34 cap = cv2.VideoCapture(device) 35 36 fps = cap.get(cv2.CAP_PROP_FPS) 37 print(fps,"fps") 38 39 #####追加 40 #########################読み込みファイルごとにここ変更##################################### 41 f = open('gazedata.txt', 'r') 42 43 datalist = f.readlines() 44 f.close() 45 46 n=0 47 for data in datalist: 48 #\d+.\d+で小数点 49 50 result = re.findall(r'-*?\d+.\d+', data) 51 52 if len(result) != 1: 53 gt.append(result[0]) 54 gx.append(result[1]) 55 gy.append(result[2]) 56 print('t[' + str(n) + ']=' + gt[n]) 57 print('x[' + str(n) + ']=' + gx[n]) 58 print('y[' + str(n) + ']=' + gy[n]) 59 n+=1 60 61 while cap.isOpened() : 62 ftime = time.perf_counter()*1000 63 ret, frame = cap.read() 64 65 # 結果画像の初期化(imgのコピーを代入) = res 66 res = frame.copy() 67 68 #########視点表示################ 69 70 timestamps = get_timestamps('scenevideo.mp4') 71 for ts in timestamps: 72 print(ts) 73 74 #####int内を(採取数値 * 1920, 採取数値 * 1080)にする 75 res = cv2.circle(res, (int(gx[n]*1920),int(gy[n]*1080)), 8, (0, 0, 255), thickness=5) 76 interval = int((time.perf_counter()*1000-ftime)) 77 if cv2.waitKey(int(1000/fps)) & 0xFF == ord('q') or ret == False: 78 break 79 80 cv2.imshow("video", res) 81 82 cv2.destroyAllWindows() 83 cap.release() 84 85 #cv2.waitKey(0) 86 #cv2.destroyAllWindows() 87 88if __name__=='__main__': 89 main() 90 91
プログラム内で取得したタイムスタンプ
0.0 0.0 40.0 80.4 120.4 160.4 200.40000000000003 240.4 280.40000000000003 320.8 … 16109.2 16149.2 16189.199999999999 16229.600000000002
gazedata内のタイムスタンプ
t[0]=0.005122 t[1]=0.015189 t[2]=0.025215 t[3]=0.035209 t[4]=0.045195 t[5]=0.055262 t[6]=0.065288 t[7]=0.075282 t[8]=0.085268 t[9]=0.095334 t[10]=0.105360 … t[1476]=16.264572 t[1477]=16.274558 t[1478]=16.284624 t[1479]=16.294651
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/07/13 13:26
2021/07/14 01:07
2021/07/14 07:44