diff --git a/server/detector.py b/server/detector.py index 25c46e1..68a6317 100644 --- a/server/detector.py +++ b/server/detector.py @@ -98,7 +98,7 @@ class YOLOPoseHeadDetector: """ # Standard Ultralytics model — auto-downloaded on first use - DEFAULT_MODEL = "yolov8n-pose.pt" + DEFAULT_MODEL = os.path.join("models", "yolov8n-pose.pt") def __init__( self, @@ -128,6 +128,7 @@ class YOLOPoseHeadDetector: model_path = self._model_path else: model_path = self.DEFAULT_MODEL + os.makedirs(os.path.dirname(model_path), exist_ok=True) if torch.cuda.is_available(): self._device = 'cuda' diff --git a/server/main.py b/server/main.py index 6b22e27..decc232 100644 --- a/server/main.py +++ b/server/main.py @@ -492,11 +492,8 @@ def process_bake_task(task_id: str, req: BakeRequest): process_queue.put((idx, frame)) continue - # ROI processing (same as original) - min_x, min_y = src_width, src_height - max_x, max_y = 0, 0 + # 各人物ごとに個別ROIで処理(全員まとめると離れた人物間が巨大ROIになるため) valid_boxes = [] - for box in frame_boxes: if not isinstance(box, list) or len(box) < 4: continue @@ -504,42 +501,37 @@ def process_bake_task(task_id: str, req: BakeRequest): if w <= 0 or h <= 0: continue valid_boxes.append((x, y, w, h)) - min_x = min(min_x, x) - min_y = min(min_y, y) - max_x = max(max_x, x + w) - max_y = max(max_y, y + h) if not valid_boxes: process_queue.put((idx, frame)) continue - roi_x1 = max(0, min_x - blur_margin) - roi_y1 = max(0, min_y - blur_margin) - roi_x2 = min(src_width, max_x + blur_margin) - roi_y2 = min(src_height, max_y + blur_margin) - roi_width = roi_x2 - roi_x1 - roi_height = roi_y2 - roi_y1 - - if roi_width <= 0 or roi_height <= 0: - process_queue.put((idx, frame)) - continue - - roi_mask = np.zeros((roi_height, roi_width), dtype=np.uint8) for x, y, w, h in valid_boxes: + roi_x1 = max(0, x - blur_margin) + roi_y1 = max(0, y - blur_margin) + roi_x2 = min(src_width, x + w + blur_margin) + roi_y2 = min(src_height, y + h + blur_margin) + roi_width = roi_x2 - roi_x1 + roi_height = roi_y2 - roi_y1 + + if roi_width <= 0 or roi_height <= 0: + continue + + roi_mask = np.zeros((roi_height, roi_width), dtype=np.uint8) center = (x + w // 2 - roi_x1, y + h // 2 - roi_y1) axes = (max(1, w // 2), max(1, h // 2)) cv2.ellipse(roi_mask, center, axes, 0, 0, 360, 255, -1) - roi_mask = cv2.GaussianBlur(roi_mask, (feather_kernel, feather_kernel), 0) - roi_src = frame[roi_y1:roi_y2, roi_x1:roi_x2] - roi_blurred = cv2.GaussianBlur(roi_src, (blur_size, blur_size), 0) + roi_mask = cv2.GaussianBlur(roi_mask, (feather_kernel, feather_kernel), 0) + roi_src = frame[roi_y1:roi_y2, roi_x1:roi_x2] + roi_blurred = cv2.GaussianBlur(roi_src, (blur_size, blur_size), 0) - roi_alpha = (roi_mask.astype(np.float32) / 255.0)[..., np.newaxis] - roi_composed = (roi_src.astype(np.float32) * (1.0 - roi_alpha)) + ( - roi_blurred.astype(np.float32) * roi_alpha - ) + roi_alpha = (roi_mask.astype(np.float32) / 255.0)[..., np.newaxis] + roi_composed = (roi_src.astype(np.float32) * (1.0 - roi_alpha)) + ( + roi_blurred.astype(np.float32) * roi_alpha + ) + frame[roi_y1:roi_y2, roi_x1:roi_x2] = np.clip(roi_composed, 0, 255).astype(np.uint8) - frame[roi_y1:roi_y2, roi_x1:roi_x2] = np.clip(roi_composed, 0, 255).astype(np.uint8) process_queue.put((idx, frame)) except Exception as e: