import cv2 import numpy as np roi_bad_pixel_number = 500 # the number of pixel where 3 values are zero in RGB channel on ROI image roi_aspect_ratio_threshold = 200 # the passable aspect ratio threshold of ROI image cupped_pose_threshold = 3 # this value determines if hand is cupped or not frame_margin = 300 # the extra marine size of the frame inputted into Google Mediapipe Graph (this value must be a # multiple of two) roi_size_threshold = 0.23 def mat_to_bytes(mat): """ Convert cv::Mat image data (NumPy array in Python) to raw bytes. """ # Encode cv::Mat as PNG bytes is_success, buffer = cv2.imencode(".png", mat) if not is_success: raise ValueError("Failed to encode cv::Mat image") return buffer.tobytes() def img_crop(img_original, x2, x1, y2, y1, label): h, w, _ = img_original.shape img = np.zeros((h + 20, w + 20, 3), np.uint8) img[10:-10, 10:-10, :] = img_original if label == "Left": v1 = np.array([x2, y2]) v2 = np.array([x1, y1]) else: v2 = np.array([x2, y2]) v1 = np.array([x1, y1]) theta = np.arctan2((v2 - v1)[1], (v2 - v1)[0]) * 180 / np.pi R = cv2.getRotationMatrix2D(tuple([int(v2[0]), int(v2[1])]), theta, 1) v1 = (R[:, :2] @ v1 + R[:, -1]).astype(int) v2 = (R[:, :2] @ v2 + R[:, -1]).astype(int) img_r = cv2.warpAffine(img, R, (w, h)) if 1: ux = int(v1[0] - (v2 - v1)[0] * 0.05) uy = int(v1[1] + (v2 - v1)[0] * 0.05) lx = int(v2[0] + (v2 - v1)[0] * 0.05) ly = int(v2[1] + (v2 - v1)[0] * 1) else: ux = int(v1[0] - (v2 - v1)[0] * 0.1) uy = int(v1[1] + (v2 - v1)[0] * 0.1) lx = int(v2[0] + (v2 - v1)[0] * 0.1) ly = int(v2[1] + (v2 - v1)[0] * 1.2) # delta_y is movement value in y ward delta_y = (ly - uy) * 0.15 ly = int(ly - delta_y) uy = int(uy - delta_y) delta_x = (lx - ux) * 0.01 lx = int(lx + delta_x) ux = int(ux + delta_x) if label == "Right": delta_x = (lx - ux) * 0.05 lx = int(lx + delta_x) ux = int(ux + delta_x) # roi = img_r roi = img_r[uy:ly, ux:lx] if roi.shape[0] == 0 or roi.shape[1] == 0: print("error 1") return None, 3 if abs(roi.shape[0] - roi.shape[1]) > roi_aspect_ratio_threshold: print("error 2", abs(roi.shape[0] - roi.shape[1])) return None, 4 if roi.shape[1] / w < roi_size_threshold: print("error 3", roi.shape[1] / w) return None, 7 n_zeros = np.count_nonzero(roi == 0) # if n_zeros > roi_bad_pixel_number: # print("error 4", n_zeros) # return None, 5 return roi, 0 def get_roi(img, hand_type, x1, y1, x2, y2): if hand_type == 0: label = "Left" else: label = "Right" roi, _ = img_crop(img, x1, x2, y1, y2, label) cv2.imwrite('test.jpg', roi) return roi