import gradio as gr import cv2 import tempfile import numpy as np import urllib.request import os import subprocess import shutil import mediapipe as mp from mediapipe.tasks import python from mediapipe.tasks.python import vision model_url="https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task" model_path="/tmp/pose_landmarker_lite.task" if not os.path.exists(model_path): urllib.request.urlretrieve(model_url,model_path) class PoseDetector: def __init__(self,confidence=0.25): self.confidence=confidence self.prev_landmarks=None self.setup_detector(confidence) def setup_detector(self,confidence): base_options=python.BaseOptions(model_asset_path=model_path) options=vision.PoseLandmarkerOptions( base_options=base_options, running_mode=vision.RunningMode.VIDEO, num_poses=1, min_pose_detection_confidence=confidence, min_pose_presence_confidence=confidence, min_tracking_confidence=confidence, output_segmentation_masks=True) self.pose_landmarker=vision.PoseLandmarker.create_from_options(options) def enhance_image(self,frame): lab=cv2.cvtColor(frame,cv2.COLOR_BGR2LAB) l,a,b=cv2.split(lab) clahe=cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8)) l=clahe.apply(l) enhanced=cv2.merge([l,a,b]) enhanced=cv2.cvtColor(enhanced,cv2.COLOR_LAB2BGR) kernel=np.array([[-0.5,-0.5,-0.5],[-0.5,5,-0.5],[-0.5,-0.5,-0.5]]) enhanced=cv2.filter2D(enhanced,-1,kernel) enhanced=cv2.convertScaleAbs(enhanced,alpha=1.1,beta=10) return enhanced def remove_background(self,frame,segmentation_mask): if segmentation_mask is None: return frame try: mask=segmentation_mask.numpy_view() if mask.shape[:2]!=(frame.shape[0],frame.shape[1]): mask=cv2.resize(mask,(frame.shape[1],frame.shape[0])) binary_mask=(mask>0.5).astype(np.uint8)*255 kernel=np.ones((5,5),np.uint8) binary_mask=cv2.morphologyEx(binary_mask,cv2.MORPH_CLOSE,kernel) binary_mask=cv2.morphologyEx(binary_mask,cv2.MORPH_OPEN,kernel) background=np.zeros_like(frame) mask_3ch=cv2.cvtColor(binary_mask,cv2.COLOR_GRAY2BGR)/255.0 result=(frame*mask_3ch+background*(1-mask_3ch)).astype(np.uint8) return result except: return frame def temporal_smoothing(self,current_landmarks,alpha=0.7): if self.prev_landmarks is None or len(self.prev_landmarks)!=len(current_landmarks): self.prev_landmarks=current_landmarks return current_landmarks smoothed=[] for i in range(len(current_landmarks)): class SmoothLandmark:pass landmark=SmoothLandmark() landmark.x=alpha*current_landmarks[i].x+(1-alpha)*self.prev_landmarks[i].x landmark.y=alpha*current_landmarks[i].y+(1-alpha)*self.prev_landmarks[i].y landmark.z=alpha*current_landmarks[i].z+(1-alpha)*self.prev_landmarks[i].z landmark.visibility=current_landmarks[i].visibility smoothed.append(landmark) self.prev_landmarks=smoothed return smoothed def detect_pose_multi_pass(self,frame,timestamp_ms): rgb_frame=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB) mp_image=mp.Image(image_format=mp.ImageFormat.SRGB,data=rgb_frame) result=self.pose_landmarker.detect_for_video(mp_image,timestamp_ms) if result.pose_landmarks: return result,frame enhanced_frame=self.enhance_image(frame) rgb_enhanced=cv2.cvtColor(enhanced_frame,cv2.COLOR_BGR2RGB) mp_image_enhanced=mp.Image(image_format=mp.ImageFormat.SRGB,data=rgb_enhanced) result=self.pose_landmarker.detect_for_video(mp_image_enhanced,timestamp_ms) if result.pose_landmarks: return result,enhanced_frame return None,frame SIMPLER_CONNECTIONS=[(11,12),(11,23),(12,24),(23,24),(11,13),(13,15),(12,14),(14,16),(23,25),(25,27),(24,26),(26,28)] def draw_landmarks(frame,landmarks): h,w=frame.shape[:2] for connection in SIMPLER_CONNECTIONS: idx1,idx2=connection if idx10.5 and landmarks[idx2].visibility>0.5: pt1=(int(landmarks[idx1].x*w),int(landmarks[idx1].y*h)) pt2=(int(landmarks[idx2].x*w),int(landmarks[idx2].y*h)) if 0<=pt1[0]0.5: x=int(landmark.x*w) y=int(landmark.y*h) if 0<=x