| from typing import Union, Iterable, Tuple |
| import numpy as np |
| import torch |
| import cv2 |
| from sklearn.metrics import roc_auc_score |
| from sklearn.metrics import average_precision_score |
|
|
|
|
| def auc(heatmap, onehot_im, is_im=True): |
| if is_im: |
| auc_score = roc_auc_score( |
| np.reshape(onehot_im, onehot_im.size), np.reshape(heatmap, heatmap.size) |
| ) |
| else: |
| auc_score = roc_auc_score(onehot_im, heatmap) |
| return auc_score |
|
|
|
|
| def ap(label, pred): |
| return average_precision_score(label, pred) |
|
|
|
|
| def argmax_pts(heatmap): |
| idx = np.unravel_index(heatmap.argmax(), heatmap.shape) |
| pred_y, pred_x = map(float, idx) |
| return pred_x, pred_y |
|
|
|
|
| def L2_dist(p1, p2): |
| return np.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) |
|
|
|
|
| def multi_hot_targets(gaze_pts, out_res): |
| w, h = out_res |
| target_map = np.zeros((h, w)) |
| for p in gaze_pts: |
| if p[0] >= 0: |
| x, y = map(int, [p[0] * w.float(), p[1] * h.float()]) |
| x = min(x, w - 1) |
| y = min(y, h - 1) |
| target_map[y, x] = 1 |
| return target_map |
|
|
|
|
| def inverse_transform(tensor: torch.Tensor) -> np.ndarray: |
| tensor = tensor.detach().cpu().permute(0, 2, 3, 1) |
| mean = torch.tensor([0.485, 0.456, 0.406]) |
| std = torch.tensor([0.229, 0.224, 0.225]) |
| tensor = tensor * std + mean |
| return cv2.cvtColor((tensor.numpy() * 255).astype(np.uint8)[0], cv2.COLOR_RGB2BGR) |
|
|
|
|
| def draw(data, heatmap, out_path, on_img=True): |
| img = inverse_transform(data["images"]) |
| head_channel = cv2.applyColorMap( |
| (data["head_channels"].squeeze().detach().cpu().numpy() * 255).astype(np.uint8), |
| cv2.COLORMAP_BONE, |
| ) |
| hm = cv2.applyColorMap((heatmap * 255).astype(np.uint8), cv2.COLORMAP_JET) |
| heatmap = hm |
| heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0])) |
| if on_img: |
| img = cv2.addWeighted(img, 1, heatmap, 0.5, 1) |
| else: |
| img = heatmap |
| |
| cv2.imwrite(out_path, img) |
|
|
|
|
| def draw_origin_img(data, out_path): |
| img = inverse_transform(data["images"]) |
| hm = cv2.applyColorMap( |
| (data["heatmaps"].squeeze().detach().cpu().numpy() * 255).astype(np.uint8), |
| cv2.COLORMAP_JET, |
| ) |
| hm[data["heatmaps"].squeeze().detach().cpu().numpy() == 0] = 0 |
| hm = cv2.resize(hm, (img.shape[1], img.shape[0])) |
| head_channel = cv2.applyColorMap( |
| (data["head_channels"].squeeze().detach().cpu().numpy() * 255).astype(np.uint8), |
| cv2.COLORMAP_BONE, |
| ) |
| head_channel[data["head_channels"].squeeze().detach().cpu().numpy() < 0.1] = 0 |
| hm = cv2.resize(hm, (img.shape[1], img.shape[0])) |
| ori = cv2.addWeighted(img, 1, hm, 0.5, 1) |
| ori = cv2.addWeighted(ori, 1, head_channel, 0.1, 1) |
| cv2.imwrite(out_path, ori) |
|
|
|
|
| class __Image2MP4: |
| def __init__(self): |
| self.Fourcc = cv2.VideoWriter_fourcc(*"mp4v") |
|
|
| def __call__( |
| self, |
| frames: Union[Iterable[np.ndarray], str], |
| path: str, |
| fps: float = 30.0, |
| isize: Tuple[int, int] = None, |
| ): |
| if isinstance(frames, str): |
| from os import listdir, path as osp |
|
|
| imgs = sorted(listdir(frames)) |
| frames = [ |
| cv2.imread(osp.join(frames, img), cv2.IMREAD_COLOR) for img in imgs |
| ] |
|
|
| if isize is None: |
| isize = (frames[0].shape[1], frames[0].shape[0]) |
|
|
| output_video = cv2.VideoWriter(path, self.Fourcc, fps, isize) |
| for frame in frames: |
| frame = cv2.resize(frame, isize) |
| output_video.write(frame) |
| output_video.release() |
|
|
|
|
| img2mp4 = __Image2MP4() |
|
|
|
|
| def dark_inference(heatmap: np.ndarray, gaussian_kernel: int = 39): |
| pred_x, pred_y = argmax_pts(heatmap) |
| pred_x, pred_y = int(pred_x), int(pred_y) |
| height, width = heatmap.shape[-2:] |
| |
| orig_max = heatmap.max() |
| border = (gaussian_kernel - 1) // 2 |
| dr = np.zeros((height + 2 * border, width + 2 * border)) |
| dr[border:-border, border:-border] = heatmap.copy() |
| dr = cv2.GaussianBlur(dr, (gaussian_kernel, gaussian_kernel), 0) |
| heatmap = dr[border:-border, border:-border].copy() |
| heatmap *= orig_max / np.max(heatmap) |
| |
| heatmap = np.maximum(heatmap, 1e-10) |
| heatmap = np.log(heatmap) |
| |
| if 1 < pred_x < width - 2 and 1 < pred_y < height - 2: |
| dx = 0.5 * (heatmap[pred_y][pred_x + 1] - heatmap[pred_y][pred_x - 1]) |
| dy = 0.5 * (heatmap[pred_y + 1][pred_x] - heatmap[pred_y - 1][pred_x]) |
| dxx = 0.25 * ( |
| heatmap[pred_y][pred_x + 2] |
| - 2 * heatmap[pred_y][pred_x] |
| + heatmap[pred_y][pred_x - 2] |
| ) |
| dxy = 0.25 * ( |
| heatmap[pred_y + 1][pred_x + 1] |
| - heatmap[pred_y - 1][pred_x + 1] |
| - heatmap[pred_y + 1][pred_x - 1] |
| + heatmap[pred_y - 1][pred_x - 1] |
| ) |
| dyy = 0.25 * ( |
| heatmap[pred_y + 2][pred_x] |
| - 2 * heatmap[pred_y][pred_x] |
| + heatmap[pred_y - 2][pred_x] |
| ) |
| derivative = np.matrix([[dx],[dy]]) |
| hessian = np.matrix([[dxx,dxy],[dxy,dyy]]) |
| if dxx * dyy - dxy ** 2 != 0: |
| hessianinv = hessian.I |
| offset = -hessianinv * derivative |
| offset_x, offset_y = np.squeeze(np.array(offset.T), axis=0) |
| pred_x += offset_x |
| pred_y += offset_y |
| return pred_x, pred_y |
|
|