| |
|
|
| import os.path as osp |
| import cv2; cv2.setNumThreads(0); cv2.ocl.setUseOpenCL(False) |
| import torch |
| import numpy as np |
| import onnxruntime |
| from .timer import Timer |
| from .rprint import rlog |
| from .crop import crop_image, _transform_pts |
|
|
|
|
| def make_abs_path(fn): |
| return osp.join(osp.dirname(osp.realpath(__file__)), fn) |
|
|
|
|
| def to_ndarray(obj): |
| if isinstance(obj, torch.Tensor): |
| return obj.cpu().numpy() |
| elif isinstance(obj, np.ndarray): |
| return obj |
| else: |
| return np.array(obj) |
|
|
|
|
| class LandmarkRunner(object): |
| """landmark runner""" |
| def __init__(self, **kwargs): |
| ckpt_path = kwargs.get('ckpt_path') |
| onnx_provider = 'cpu' |
| device_id = kwargs.get('device_id', 0) |
| self.dsize = kwargs.get('dsize', 224) |
| self.timer = Timer() |
|
|
| if onnx_provider.lower() == 'cuda': |
| self.session = onnxruntime.InferenceSession( |
| ckpt_path, providers=[ |
| ('CUDAExecutionProvider', {'device_id': device_id}) |
| ] |
| ) |
| else: |
| opts = onnxruntime.SessionOptions() |
| opts.intra_op_num_threads = 4 |
| self.session = onnxruntime.InferenceSession( |
| ckpt_path, providers=['CPUExecutionProvider'], |
| sess_options=opts |
| ) |
|
|
| def _run(self, inp): |
| out = self.session.run(None, {'input': inp}) |
| return out |
|
|
| def run(self, img_rgb: np.ndarray, lmk=None): |
| if lmk is not None: |
| crop_dct = crop_image(img_rgb, lmk, dsize=self.dsize, scale=1.5, vy_ratio=-0.1) |
| img_crop_rgb = crop_dct['img_crop'] |
| else: |
| img_crop_rgb = cv2.resize(img_rgb, (self.dsize, self.dsize)) |
| scale = max(img_rgb.shape[:2]) / self.dsize |
| crop_dct = { |
| 'M_c2o': np.array([ |
| [scale, 0., 0.], |
| [0., scale, 0.], |
| [0., 0., 1.], |
| ], dtype=np.float32), |
| } |
|
|
| inp = (img_crop_rgb.astype(np.float32) / 255.).transpose(2, 0, 1)[None, ...] |
|
|
| out_lst = self._run(inp) |
| out_pts = out_lst[2] |
|
|
| pts = to_ndarray(out_pts[0]).reshape(-1, 2) * self.dsize |
| pts = _transform_pts(pts, M=crop_dct['M_c2o']) |
|
|
| return { |
| 'pts': pts, |
| } |
|
|
| def warmup(self): |
| |
| self.timer.tic() |
|
|
| dummy_image = np.zeros((1, 3, self.dsize, self.dsize), dtype=np.float32) |
|
|
| _ = self._run(dummy_image) |
|
|
| elapse = self.timer.toc() |
| rlog(f'LandmarkRunner warmup time: {elapse:.3f}s') |
|
|