action_infer.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import os
  15. import yaml
  16. import glob
  17. import cv2
  18. import numpy as np
  19. import math
  20. import paddle
  21. import sys
  22. from collections import Sequence
  23. # add deploy path of PadleDetection to sys.path
  24. parent_path = os.path.abspath(os.path.join(__file__, *(['..'] * 2)))
  25. sys.path.insert(0, parent_path)
  26. from paddle.inference import Config, create_predictor
  27. from python.utils import argsparser, Timer, get_current_memory_mb
  28. from python.benchmark_utils import PaddleInferBenchmark
  29. from python.infer import Detector, print_arguments
  30. from attr_infer import AttrDetector
  31. class SkeletonActionRecognizer(Detector):
  32. """
  33. Args:
  34. model_dir (str): root path of model.pdiparams, model.pdmodel and infer_cfg.yml
  35. device (str): Choose the device you want to run, it can be: CPU/GPU/XPU, default is CPU
  36. run_mode (str): mode of running(paddle/trt_fp32/trt_fp16)
  37. batch_size (int): size of pre batch in inference
  38. trt_min_shape (int): min shape for dynamic shape in trt
  39. trt_max_shape (int): max shape for dynamic shape in trt
  40. trt_opt_shape (int): opt shape for dynamic shape in trt
  41. trt_calib_mode (bool): If the model is produced by TRT offline quantitative
  42. calibration, trt_calib_mode need to set True
  43. cpu_threads (int): cpu threads
  44. enable_mkldnn (bool): whether to open MKLDNN
  45. threshold (float): The threshold of score for visualization
  46. window_size(int): Temporal size of skeleton feature.
  47. random_pad (bool): Whether do random padding when frame length < window_size.
  48. """
  49. def __init__(self,
  50. model_dir,
  51. device='CPU',
  52. run_mode='paddle',
  53. batch_size=1,
  54. trt_min_shape=1,
  55. trt_max_shape=1280,
  56. trt_opt_shape=640,
  57. trt_calib_mode=False,
  58. cpu_threads=1,
  59. enable_mkldnn=False,
  60. output_dir='output',
  61. threshold=0.5,
  62. window_size=100,
  63. random_pad=False):
  64. assert batch_size == 1, "SkeletonActionRecognizer only support batch_size=1 now."
  65. super(SkeletonActionRecognizer, self).__init__(
  66. model_dir=model_dir,
  67. device=device,
  68. run_mode=run_mode,
  69. batch_size=batch_size,
  70. trt_min_shape=trt_min_shape,
  71. trt_max_shape=trt_max_shape,
  72. trt_opt_shape=trt_opt_shape,
  73. trt_calib_mode=trt_calib_mode,
  74. cpu_threads=cpu_threads,
  75. enable_mkldnn=enable_mkldnn,
  76. output_dir=output_dir,
  77. threshold=threshold,
  78. delete_shuffle_pass=True)
  79. @classmethod
  80. def init_with_cfg(cls, args, cfg):
  81. return cls(model_dir=cfg['model_dir'],
  82. batch_size=cfg['batch_size'],
  83. window_size=cfg['max_frames'],
  84. device=args.device,
  85. run_mode=args.run_mode,
  86. trt_min_shape=args.trt_min_shape,
  87. trt_max_shape=args.trt_max_shape,
  88. trt_opt_shape=args.trt_opt_shape,
  89. trt_calib_mode=args.trt_calib_mode,
  90. cpu_threads=args.cpu_threads,
  91. enable_mkldnn=args.enable_mkldnn)
  92. def predict(self, repeats=1):
  93. '''
  94. Args:
  95. repeats (int): repeat number for prediction
  96. Returns:
  97. results (dict):
  98. '''
  99. # model prediction
  100. output_names = self.predictor.get_output_names()
  101. for i in range(repeats):
  102. self.predictor.run()
  103. output_tensor = self.predictor.get_output_handle(output_names[0])
  104. np_output = output_tensor.copy_to_cpu()
  105. result = dict(output=np_output)
  106. return result
  107. def predict_skeleton(self, skeleton_list, run_benchmark=False, repeats=1):
  108. results = []
  109. for i, skeleton in enumerate(skeleton_list):
  110. if run_benchmark:
  111. # preprocess
  112. inputs = self.preprocess(skeleton) # warmup
  113. self.det_times.preprocess_time_s.start()
  114. inputs = self.preprocess(skeleton)
  115. self.det_times.preprocess_time_s.end()
  116. # model prediction
  117. result = self.predict(repeats=repeats) # warmup
  118. self.det_times.inference_time_s.start()
  119. result = self.predict(repeats=repeats)
  120. self.det_times.inference_time_s.end(repeats=repeats)
  121. # postprocess
  122. result_warmup = self.postprocess(inputs, result) # warmup
  123. self.det_times.postprocess_time_s.start()
  124. result = self.postprocess(inputs, result)
  125. self.det_times.postprocess_time_s.end()
  126. self.det_times.img_num += len(skeleton)
  127. cm, gm, gu = get_current_memory_mb()
  128. self.cpu_mem += cm
  129. self.gpu_mem += gm
  130. self.gpu_util += gu
  131. else:
  132. # preprocess
  133. self.det_times.preprocess_time_s.start()
  134. inputs = self.preprocess(skeleton)
  135. self.det_times.preprocess_time_s.end()
  136. # model prediction
  137. self.det_times.inference_time_s.start()
  138. result = self.predict()
  139. self.det_times.inference_time_s.end()
  140. # postprocess
  141. self.det_times.postprocess_time_s.start()
  142. result = self.postprocess(inputs, result)
  143. self.det_times.postprocess_time_s.end()
  144. self.det_times.img_num += len(skeleton)
  145. results.append(result)
  146. return results
  147. def predict_skeleton_with_mot(self, skeleton_with_mot, run_benchmark=False):
  148. """
  149. skeleton_with_mot (dict): includes individual skeleton sequences, which shape is [C, T, K, 1]
  150. and its corresponding track id.
  151. """
  152. skeleton_list = skeleton_with_mot["skeleton"]
  153. mot_id = skeleton_with_mot["mot_id"]
  154. act_res = self.predict_skeleton(skeleton_list, run_benchmark, repeats=1)
  155. results = list(zip(mot_id, act_res))
  156. return results
  157. def preprocess(self, data):
  158. preprocess_ops = []
  159. for op_info in self.pred_config.preprocess_infos:
  160. new_op_info = op_info.copy()
  161. op_type = new_op_info.pop('type')
  162. preprocess_ops.append(eval(op_type)(**new_op_info))
  163. input_lst = []
  164. data = action_preprocess(data, preprocess_ops)
  165. input_lst.append(data)
  166. input_names = self.predictor.get_input_names()
  167. inputs = {}
  168. inputs['data_batch_0'] = np.stack(input_lst, axis=0).astype('float32')
  169. for i in range(len(input_names)):
  170. input_tensor = self.predictor.get_input_handle(input_names[i])
  171. input_tensor.copy_from_cpu(inputs[input_names[i]])
  172. return inputs
  173. def postprocess(self, inputs, result):
  174. # postprocess output of predictor
  175. output_logit = result['output'][0]
  176. classes = np.argpartition(output_logit, -1)[-1:]
  177. classes = classes[np.argsort(-output_logit[classes])]
  178. scores = output_logit[classes]
  179. result = {'class': classes, 'score': scores}
  180. return result
  181. def action_preprocess(input, preprocess_ops):
  182. """
  183. input (str | numpy.array): if input is str, it should be a legal file path with numpy array saved.
  184. Otherwise it should be numpy.array as direct input.
  185. return (numpy.array)
  186. """
  187. if isinstance(input, str):
  188. assert os.path.isfile(input) is not None, "{0} not exists".format(input)
  189. data = np.load(input)
  190. else:
  191. data = input
  192. for operator in preprocess_ops:
  193. data = operator(data)
  194. return data
  195. class AutoPadding(object):
  196. """
  197. Sample or Padding frame skeleton feature.
  198. Args:
  199. window_size (int): Temporal size of skeleton feature.
  200. random_pad (bool): Whether do random padding when frame length < window size. Default: False.
  201. """
  202. def __init__(self, window_size=100, random_pad=False):
  203. self.window_size = window_size
  204. self.random_pad = random_pad
  205. def get_frame_num(self, data):
  206. C, T, V, M = data.shape
  207. for i in range(T - 1, -1, -1):
  208. tmp = np.sum(data[:, i, :, :])
  209. if tmp > 0:
  210. T = i + 1
  211. break
  212. return T
  213. def __call__(self, results):
  214. data = results
  215. C, T, V, M = data.shape
  216. T = self.get_frame_num(data)
  217. if T == self.window_size:
  218. data_pad = data[:, :self.window_size, :, :]
  219. elif T < self.window_size:
  220. begin = random.randint(
  221. 0, self.window_size - T) if self.random_pad else 0
  222. data_pad = np.zeros((C, self.window_size, V, M))
  223. data_pad[:, begin:begin + T, :, :] = data[:, :T, :, :]
  224. else:
  225. if self.random_pad:
  226. index = np.random.choice(
  227. T, self.window_size, replace=False).astype('int64')
  228. else:
  229. index = np.linspace(0, T, self.window_size).astype("int64")
  230. data_pad = data[:, index, :, :]
  231. return data_pad
  232. def get_test_skeletons(input_file):
  233. assert input_file is not None, "--action_file can not be None"
  234. input_data = np.load(input_file)
  235. if input_data.ndim == 4:
  236. return [input_data]
  237. elif input_data.ndim == 5:
  238. output = list(
  239. map(lambda x: np.squeeze(x, 0),
  240. np.split(input_data, input_data.shape[0], 0)))
  241. return output
  242. else:
  243. raise ValueError(
  244. "Now only support input with shape: (N, C, T, K, M) or (C, T, K, M)")
  245. class DetActionRecognizer(object):
  246. """
  247. Args:
  248. model_dir (str): root path of model.pdiparams, model.pdmodel and infer_cfg.yml
  249. device (str): Choose the device you want to run, it can be: CPU/GPU/XPU, default is CPU
  250. run_mode (str): mode of running(paddle/trt_fp32/trt_fp16)
  251. batch_size (int): size of pre batch in inference
  252. trt_min_shape (int): min shape for dynamic shape in trt
  253. trt_max_shape (int): max shape for dynamic shape in trt
  254. trt_opt_shape (int): opt shape for dynamic shape in trt
  255. trt_calib_mode (bool): If the model is produced by TRT offline quantitative
  256. calibration, trt_calib_mode need to set True
  257. cpu_threads (int): cpu threads
  258. enable_mkldnn (bool): whether to open MKLDNN
  259. threshold (float): The threshold of score for action feature object detection.
  260. display_frames (int): The duration for corresponding detected action.
  261. skip_frame_num (int): The number of frames for interval prediction. A skipped frame will
  262. reuse the result of its last frame. If it is set to 0, no frame will be skipped. Default
  263. is 0.
  264. """
  265. def __init__(self,
  266. model_dir,
  267. device='CPU',
  268. run_mode='paddle',
  269. batch_size=1,
  270. trt_min_shape=1,
  271. trt_max_shape=1280,
  272. trt_opt_shape=640,
  273. trt_calib_mode=False,
  274. cpu_threads=1,
  275. enable_mkldnn=False,
  276. output_dir='output',
  277. threshold=0.5,
  278. display_frames=20,
  279. skip_frame_num=0):
  280. super(DetActionRecognizer, self).__init__()
  281. self.detector = Detector(
  282. model_dir=model_dir,
  283. device=device,
  284. run_mode=run_mode,
  285. batch_size=batch_size,
  286. trt_min_shape=trt_min_shape,
  287. trt_max_shape=trt_max_shape,
  288. trt_opt_shape=trt_opt_shape,
  289. trt_calib_mode=trt_calib_mode,
  290. cpu_threads=cpu_threads,
  291. enable_mkldnn=enable_mkldnn,
  292. output_dir=output_dir,
  293. threshold=threshold)
  294. self.threshold = threshold
  295. self.frame_life = display_frames
  296. self.result_history = {}
  297. self.skip_frame_num = skip_frame_num
  298. self.skip_frame_cnt = 0
  299. self.id_in_last_frame = []
  300. @classmethod
  301. def init_with_cfg(cls, args, cfg):
  302. return cls(model_dir=cfg['model_dir'],
  303. batch_size=cfg['batch_size'],
  304. threshold=cfg['threshold'],
  305. display_frames=cfg['display_frames'],
  306. skip_frame_num=cfg['skip_frame_num'],
  307. device=args.device,
  308. run_mode=args.run_mode,
  309. trt_min_shape=args.trt_min_shape,
  310. trt_max_shape=args.trt_max_shape,
  311. trt_opt_shape=args.trt_opt_shape,
  312. trt_calib_mode=args.trt_calib_mode,
  313. cpu_threads=args.cpu_threads,
  314. enable_mkldnn=args.enable_mkldnn)
  315. def predict(self, images, mot_result):
  316. if self.skip_frame_cnt == 0 or (not self.check_id_is_same(mot_result)):
  317. det_result = self.detector.predict_image(images, visual=False)
  318. result = self.postprocess(det_result, mot_result)
  319. else:
  320. result = self.reuse_result(mot_result)
  321. self.skip_frame_cnt += 1
  322. if self.skip_frame_cnt >= self.skip_frame_num:
  323. self.skip_frame_cnt = 0
  324. return result
  325. def postprocess(self, det_result, mot_result):
  326. np_boxes_num = det_result['boxes_num']
  327. if np_boxes_num[0] <= 0:
  328. return [[], []]
  329. mot_bboxes = mot_result.get('boxes')
  330. cur_box_idx = 0
  331. mot_id = []
  332. act_res = []
  333. for idx in range(len(mot_bboxes)):
  334. tracker_id = mot_bboxes[idx, 0]
  335. # Current now, class 0 is positive, class 1 is negative.
  336. action_ret = {'class': 1.0, 'score': -1.0}
  337. box_num = np_boxes_num[idx]
  338. boxes = det_result['boxes'][cur_box_idx:cur_box_idx + box_num]
  339. cur_box_idx += box_num
  340. isvalid = (boxes[:, 1] > self.threshold) & (boxes[:, 0] == 0)
  341. valid_boxes = boxes[isvalid, :]
  342. if valid_boxes.shape[0] >= 1:
  343. action_ret['class'] = valid_boxes[0, 0]
  344. action_ret['score'] = valid_boxes[0, 1]
  345. self.result_history[
  346. tracker_id] = [0, self.frame_life, valid_boxes[0, 1]]
  347. else:
  348. history_det, life_remain, history_score = self.result_history.get(
  349. tracker_id, [1, self.frame_life, -1.0])
  350. action_ret['class'] = history_det
  351. action_ret['score'] = -1.0
  352. life_remain -= 1
  353. if life_remain <= 0 and tracker_id in self.result_history:
  354. del (self.result_history[tracker_id])
  355. elif tracker_id in self.result_history:
  356. self.result_history[tracker_id][1] = life_remain
  357. else:
  358. self.result_history[tracker_id] = [
  359. history_det, life_remain, history_score
  360. ]
  361. mot_id.append(tracker_id)
  362. act_res.append(action_ret)
  363. result = list(zip(mot_id, act_res))
  364. self.id_in_last_frame = mot_id
  365. return result
  366. def check_id_is_same(self, mot_result):
  367. mot_bboxes = mot_result.get('boxes')
  368. for idx in range(len(mot_bboxes)):
  369. tracker_id = mot_bboxes[idx, 0]
  370. if tracker_id not in self.id_in_last_frame:
  371. return False
  372. return True
  373. def reuse_result(self, mot_result):
  374. # This function reusing previous results of the same ID directly.
  375. mot_bboxes = mot_result.get('boxes')
  376. mot_id = []
  377. act_res = []
  378. for idx in range(len(mot_bboxes)):
  379. tracker_id = mot_bboxes[idx, 0]
  380. history_cls, life_remain, history_score = self.result_history.get(
  381. tracker_id, [1, 0, -1.0])
  382. life_remain -= 1
  383. if tracker_id in self.result_history:
  384. self.result_history[tracker_id][1] = life_remain
  385. action_ret = {'class': history_cls, 'score': history_score}
  386. mot_id.append(tracker_id)
  387. act_res.append(action_ret)
  388. result = list(zip(mot_id, act_res))
  389. self.id_in_last_frame = mot_id
  390. return result
  391. class ClsActionRecognizer(AttrDetector):
  392. """
  393. Args:
  394. model_dir (str): root path of model.pdiparams, model.pdmodel and infer_cfg.yml
  395. device (str): Choose the device you want to run, it can be: CPU/GPU/XPU, default is CPU
  396. run_mode (str): mode of running(paddle/trt_fp32/trt_fp16)
  397. batch_size (int): size of pre batch in inference
  398. trt_min_shape (int): min shape for dynamic shape in trt
  399. trt_max_shape (int): max shape for dynamic shape in trt
  400. trt_opt_shape (int): opt shape for dynamic shape in trt
  401. trt_calib_mode (bool): If the model is produced by TRT offline quantitative
  402. calibration, trt_calib_mode need to set True
  403. cpu_threads (int): cpu threads
  404. enable_mkldnn (bool): whether to open MKLDNN
  405. threshold (float): The threshold of score for action feature object detection.
  406. display_frames (int): The duration for corresponding detected action.
  407. skip_frame_num (int): The number of frames for interval prediction. A skipped frame will
  408. reuse the result of its last frame. If it is set to 0, no frame will be skipped. Default
  409. is 0.
  410. """
  411. def __init__(self,
  412. model_dir,
  413. device='CPU',
  414. run_mode='paddle',
  415. batch_size=1,
  416. trt_min_shape=1,
  417. trt_max_shape=1280,
  418. trt_opt_shape=640,
  419. trt_calib_mode=False,
  420. cpu_threads=1,
  421. enable_mkldnn=False,
  422. output_dir='output',
  423. threshold=0.5,
  424. display_frames=80,
  425. skip_frame_num=0):
  426. super(ClsActionRecognizer, self).__init__(
  427. model_dir=model_dir,
  428. device=device,
  429. run_mode=run_mode,
  430. batch_size=batch_size,
  431. trt_min_shape=trt_min_shape,
  432. trt_max_shape=trt_max_shape,
  433. trt_opt_shape=trt_opt_shape,
  434. trt_calib_mode=trt_calib_mode,
  435. cpu_threads=cpu_threads,
  436. enable_mkldnn=enable_mkldnn,
  437. output_dir=output_dir,
  438. threshold=threshold)
  439. self.threshold = threshold
  440. self.frame_life = display_frames
  441. self.result_history = {}
  442. self.skip_frame_num = skip_frame_num
  443. self.skip_frame_cnt = 0
  444. self.id_in_last_frame = []
  445. @classmethod
  446. def init_with_cfg(cls, args, cfg):
  447. return cls(model_dir=cfg['model_dir'],
  448. batch_size=cfg['batch_size'],
  449. threshold=cfg['threshold'],
  450. display_frames=cfg['display_frames'],
  451. skip_frame_num=cfg['skip_frame_num'],
  452. device=args.device,
  453. run_mode=args.run_mode,
  454. trt_min_shape=args.trt_min_shape,
  455. trt_max_shape=args.trt_max_shape,
  456. trt_opt_shape=args.trt_opt_shape,
  457. trt_calib_mode=args.trt_calib_mode,
  458. cpu_threads=args.cpu_threads,
  459. enable_mkldnn=args.enable_mkldnn)
  460. def predict_with_mot(self, images, mot_result):
  461. if self.skip_frame_cnt == 0 or (not self.check_id_is_same(mot_result)):
  462. images = self.crop_half_body(images)
  463. cls_result = self.predict_image(images, visual=False)["output"]
  464. result = self.match_action_with_id(cls_result, mot_result)
  465. else:
  466. result = self.reuse_result(mot_result)
  467. self.skip_frame_cnt += 1
  468. if self.skip_frame_cnt >= self.skip_frame_num:
  469. self.skip_frame_cnt = 0
  470. return result
  471. def crop_half_body(self, images):
  472. crop_images = []
  473. for image in images:
  474. h = image.shape[0]
  475. crop_images.append(image[:h // 2 + 1, :, :])
  476. return crop_images
  477. def postprocess(self, inputs, result):
  478. # postprocess output of predictor
  479. im_results = result['output']
  480. batch_res = []
  481. for res in im_results:
  482. action_res = res.tolist()
  483. for cid, score in enumerate(action_res):
  484. action_res[cid] = score
  485. batch_res.append(action_res)
  486. result = {'output': batch_res}
  487. return result
  488. def match_action_with_id(self, cls_result, mot_result):
  489. mot_bboxes = mot_result.get('boxes')
  490. mot_id = []
  491. act_res = []
  492. for idx in range(len(mot_bboxes)):
  493. tracker_id = mot_bboxes[idx, 0]
  494. cls_id_res = 1
  495. cls_score_res = -1.0
  496. for cls_id in range(len(cls_result[idx])):
  497. score = cls_result[idx][cls_id]
  498. if score > cls_score_res:
  499. cls_id_res = cls_id
  500. cls_score_res = score
  501. # Current now, class 0 is positive, class 1 is negative.
  502. if cls_id_res == 1 or (cls_id_res == 0 and
  503. cls_score_res < self.threshold):
  504. history_cls, life_remain, history_score = self.result_history.get(
  505. tracker_id, [1, self.frame_life, -1.0])
  506. cls_id_res = history_cls
  507. cls_score_res = 1 - cls_score_res
  508. life_remain -= 1
  509. if life_remain <= 0 and tracker_id in self.result_history:
  510. del (self.result_history[tracker_id])
  511. elif tracker_id in self.result_history:
  512. self.result_history[tracker_id][1] = life_remain
  513. else:
  514. self.result_history[
  515. tracker_id] = [cls_id_res, life_remain, cls_score_res]
  516. else:
  517. self.result_history[
  518. tracker_id] = [cls_id_res, self.frame_life, cls_score_res]
  519. action_ret = {'class': cls_id_res, 'score': cls_score_res}
  520. mot_id.append(tracker_id)
  521. act_res.append(action_ret)
  522. result = list(zip(mot_id, act_res))
  523. self.id_in_last_frame = mot_id
  524. return result
  525. def check_id_is_same(self, mot_result):
  526. mot_bboxes = mot_result.get('boxes')
  527. for idx in range(len(mot_bboxes)):
  528. tracker_id = mot_bboxes[idx, 0]
  529. if tracker_id not in self.id_in_last_frame:
  530. return False
  531. return True
  532. def reuse_result(self, mot_result):
  533. # This function reusing previous results of the same ID directly.
  534. mot_bboxes = mot_result.get('boxes')
  535. mot_id = []
  536. act_res = []
  537. for idx in range(len(mot_bboxes)):
  538. tracker_id = mot_bboxes[idx, 0]
  539. history_cls, life_remain, history_score = self.result_history.get(
  540. tracker_id, [1, 0, -1.0])
  541. life_remain -= 1
  542. if tracker_id in self.result_history:
  543. self.result_history[tracker_id][1] = life_remain
  544. action_ret = {'class': history_cls, 'score': history_score}
  545. mot_id.append(tracker_id)
  546. act_res.append(action_ret)
  547. result = list(zip(mot_id, act_res))
  548. self.id_in_last_frame = mot_id
  549. return result
  550. def main():
  551. detector = SkeletonActionRecognizer(
  552. FLAGS.model_dir,
  553. device=FLAGS.device,
  554. run_mode=FLAGS.run_mode,
  555. batch_size=FLAGS.batch_size,
  556. trt_min_shape=FLAGS.trt_min_shape,
  557. trt_max_shape=FLAGS.trt_max_shape,
  558. trt_opt_shape=FLAGS.trt_opt_shape,
  559. trt_calib_mode=FLAGS.trt_calib_mode,
  560. cpu_threads=FLAGS.cpu_threads,
  561. enable_mkldnn=FLAGS.enable_mkldnn,
  562. threshold=FLAGS.threshold,
  563. output_dir=FLAGS.output_dir,
  564. window_size=FLAGS.window_size,
  565. random_pad=FLAGS.random_pad)
  566. # predict from numpy array
  567. input_list = get_test_skeletons(FLAGS.action_file)
  568. detector.predict_skeleton(input_list, FLAGS.run_benchmark, repeats=10)
  569. if not FLAGS.run_benchmark:
  570. detector.det_times.info(average=True)
  571. else:
  572. mems = {
  573. 'cpu_rss_mb': detector.cpu_mem / len(input_list),
  574. 'gpu_rss_mb': detector.gpu_mem / len(input_list),
  575. 'gpu_util': detector.gpu_util * 100 / len(input_list)
  576. }
  577. perf_info = detector.det_times.report(average=True)
  578. model_dir = FLAGS.model_dir
  579. mode = FLAGS.run_mode
  580. model_info = {
  581. 'model_name': model_dir.strip('/').split('/')[-1],
  582. 'precision': mode.split('_')[-1]
  583. }
  584. data_info = {
  585. 'batch_size': FLAGS.batch_size,
  586. 'shape': "dynamic_shape",
  587. 'data_num': perf_info['img_num']
  588. }
  589. det_log = PaddleInferBenchmark(detector.config, model_info, data_info,
  590. perf_info, mems)
  591. det_log('SkeletonAction')
  592. if __name__ == '__main__':
  593. paddle.enable_static()
  594. parser = argsparser()
  595. FLAGS = parser.parse_args()
  596. print_arguments(FLAGS)
  597. FLAGS.device = FLAGS.device.upper()
  598. assert FLAGS.device in ['CPU', 'GPU', 'XPU'
  599. ], "device should be CPU, GPU or XPU"
  600. assert not FLAGS.use_gpu, "use_gpu has been deprecated, please use --device"
  601. main()