| | import cv2 |
| | import json |
| | import numpy as np |
| | import math |
| | import time |
| | from scipy.ndimage.filters import gaussian_filter |
| | import matplotlib.pyplot as plt |
| | import matplotlib |
| | import torch |
| | from skimage.measure import label |
| |
|
| | from .model import handpose_model |
| | from . import util |
| |
|
| | class Hand(object): |
| | def __init__(self, model_path): |
| | self.model = handpose_model() |
| | |
| | |
| | |
| | model_dict = util.transfer(self.model, torch.load(model_path)) |
| | self.model.load_state_dict(model_dict) |
| | self.model.eval() |
| |
|
| | def __call__(self, oriImgRaw): |
| | scale_search = [0.5, 1.0, 1.5, 2.0] |
| | |
| | boxsize = 368 |
| | stride = 8 |
| | padValue = 128 |
| | thre = 0.05 |
| | multiplier = [x * boxsize for x in scale_search] |
| |
|
| | wsize = 128 |
| | heatmap_avg = np.zeros((wsize, wsize, 22)) |
| |
|
| | Hr, Wr, Cr = oriImgRaw.shape |
| |
|
| | oriImg = cv2.GaussianBlur(oriImgRaw, (0, 0), 0.8) |
| |
|
| | for m in range(len(multiplier)): |
| | scale = multiplier[m] |
| | imageToTest = util.smart_resize(oriImg, (scale, scale)) |
| |
|
| | imageToTest_padded, pad = util.padRightDownCorner(imageToTest, stride, padValue) |
| | im = np.transpose(np.float32(imageToTest_padded[:, :, :, np.newaxis]), (3, 2, 0, 1)) / 256 - 0.5 |
| | im = np.ascontiguousarray(im) |
| |
|
| | data = torch.from_numpy(im).float() |
| | if torch.cuda.is_available(): |
| | data = data.cuda() |
| |
|
| | with torch.no_grad(): |
| | data = data.to(self.cn_device) |
| | output = self.model(data).cpu().numpy() |
| |
|
| | |
| | heatmap = np.transpose(np.squeeze(output), (1, 2, 0)) |
| | heatmap = util.smart_resize_k(heatmap, fx=stride, fy=stride) |
| | heatmap = heatmap[:imageToTest_padded.shape[0] - pad[2], :imageToTest_padded.shape[1] - pad[3], :] |
| | heatmap = util.smart_resize(heatmap, (wsize, wsize)) |
| |
|
| | heatmap_avg += heatmap / len(multiplier) |
| |
|
| | all_peaks = [] |
| | for part in range(21): |
| | map_ori = heatmap_avg[:, :, part] |
| | one_heatmap = gaussian_filter(map_ori, sigma=3) |
| | binary = np.ascontiguousarray(one_heatmap > thre, dtype=np.uint8) |
| |
|
| | if np.sum(binary) == 0: |
| | all_peaks.append([0, 0]) |
| | continue |
| | label_img, label_numbers = label(binary, return_num=True, connectivity=binary.ndim) |
| | max_index = np.argmax([np.sum(map_ori[label_img == i]) for i in range(1, label_numbers + 1)]) + 1 |
| | label_img[label_img != max_index] = 0 |
| | map_ori[label_img == 0] = 0 |
| |
|
| | y, x = util.npmax(map_ori) |
| | y = int(float(y) * float(Hr) / float(wsize)) |
| | x = int(float(x) * float(Wr) / float(wsize)) |
| | all_peaks.append([x, y]) |
| | return np.array(all_peaks) |
| |
|
| | if __name__ == "__main__": |
| | hand_estimation = Hand('../model/hand_pose_model.pth') |
| |
|
| | |
| | test_image = '../images/hand.jpg' |
| | oriImg = cv2.imread(test_image) |
| | peaks = hand_estimation(oriImg) |
| | canvas = util.draw_handpose(oriImg, peaks, True) |
| | cv2.imshow('', canvas) |
| | cv2.waitKey(0) |