#!/usr/bin/env python3 # -*- coding: UTF-8 -*- import cv2 import numpy as np class HOGBox: """ a simple HOG-method-based human tracking box """ # mouse click flag clicked = False def __init__(self): print('Initializing HOGBox...') self.hog = cv2.HOGDescriptor() self.hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector()) self._box_init_window_name = 'Click mouse to initialize bounding box' cv2.namedWindow(self._box_init_window_name) cv2.setMouseCallback(self._box_init_window_name, self.on_mouse) print('HOGBox initialized.') def __call__(self, img): H, W = img.shape[:2] found, w = self.hog.detectMultiScale(img) rect = self.cal_rect(found[np.argmax([found[i, 2] * found[i, 3] for i in range(len(found))])], H, W) \ if len(found) else [0, 0, W, H] # biggest area # rect = self.cal_rect(found[np.argmax(w)], H, W) if len(found) else [0, 0, W, H] # biggest weight self.draw_rect(img, rect) scale = 400 / H img = cv2.resize(img, (0, 0), fx=scale, fy=scale) cv2.imshow(self._box_init_window_name, img) if self.clicked: cv2.destroyWindow(self._box_init_window_name) return self.clicked, rect def on_mouse(self, event, x, y, flags, param): """ attain mouse clicking message """ if event == cv2.EVENT_LBUTTONUP: self.clicked = True @staticmethod def cal_rect(rect, H, W): """ calculate the box size and position """ x, y, w, h = rect offset_w = int(0.4 / 2 * W) offset_h = int(0.2 / 2 * H) return [np.max([x - offset_w, 0]), # x np.max([y - offset_h, 0]), # y np.min([x + w + offset_w, W]) - np.max([x - offset_w, 0]), # w np.min([y + h + offset_h, H]) - np.max([y - offset_h, 0])] # h @staticmethod def draw_rect(img, rect): """ draw bounding box in the BB initialization window, and record current rect (x, y, w, h) """ x, y, w, h = rect pt1 = (x, y) pt2 = (x + w, y + h) cv2.rectangle(img, pt1, pt2, (60, 66, 207), 4)