MarkLilly's picture
Add files using upload-large-folder tool
45a63fb verified
Raw History Blame Contribute Delete
4.52 kB
import warnings
import os
import json
import numpy as np
import cv2
from tqdm import tqdm
import mediapipe as mp
from PIL import Image
from mediapipe.tasks import python
from mediapipe.tasks.python import vision
from mediapipe.framework.formats import landmark_pb2
from concurrent.futures import ThreadPoolExecutor, as_completed
import torch
import requests
from PIL import Image
from transformers import BlipProcessor, BlipForConditionalGeneration
warnings.filterwarnings("ignore")
class MediapipeEngine:
def __init__(self, model_asset_path='assets/gesture_recognizer.task'):
self.mp_hands = mp.solutions.hands
self.hands = self.mp_hands.Hands(static_image_mode=True, max_num_hands=10, min_detection_confidence=0.5)
self.mp_drawing = mp.solutions.drawing_utils
def __call__(self, image):
image = np.array(image)
# image = self.resize_image(image)
annotations = self.detect(image.copy())
mask = self.prepare_mask(image, annotations)
return Image.fromarray(image), Image.fromarray(mask)
def detect(self, image):
if isinstance(image, Image.Image):
image = np.array(image)
# 进行手部检测
results = self.hands.process(image)
annotations = []
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
# self.mp_drawing.draw_landmarks(
# image, hand_landmarks, self.mp_hands.HAND_CONNECTIONS)
# 获取所有关键点的坐标
coords = np.array([(lm.x, lm.y, lm.z) for lm in hand_landmarks.landmark])
# 计算边界框
x_min, y_min, _ = np.min(coords, axis=0)
x_max, y_max, _ = np.max(coords, axis=0)
# 转换为图像坐标
H, W, _ = image.shape
x_min, y_min = int(x_min * W), int(y_min * H)
x_max, y_max = int(x_max * W), int(y_max * H)
# loosen bbox
dynamic_resize = 0.15
padding = 30
bb_xpad = max(int((x_max - x_min + 1) * dynamic_resize), padding)
bb_ypad = max(int((y_max - y_min + 1) * dynamic_resize), padding)
bbx_min = max(int(x_min - bb_xpad), 0)
bbx_max = min(int(x_max + bb_xpad), W-1)
bby_min = max(int(y_min - bb_ypad), 0)
bby_max = min(int(y_max + bb_ypad), H-1)
annotations.append({
'bbox': [bbx_min, bby_min, bbx_max, bby_max],
'landmarks': coords
})
return annotations
def prepare_mask(self, image, annotations):
mask = np.zeros(image.shape[:2], dtype=np.uint8)
for annotation in annotations:
bbox = annotation['bbox']
cv2.rectangle(mask, (bbox[0], bbox[1]), (bbox[2], bbox[3]), 255, -1)
return mask
def resize_image(self, image, target_size=1024):
h, w = image.shape[:2]
# 计算长边
long_side = max(h, w)
# 计算缩放比例
scale = target_size / long_side
# 计算新的尺寸
new_h = int(h * scale)
new_w = int(w * scale)
# 使用cv2.resize进行缩放
resized_image = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_AREA)
return resized_image
class ImageCaptioner:
def __init__(self, model_name="Salesforce/blip-image-captioning-base"):
self.processor = BlipProcessor.from_pretrained(model_name)
self.model = BlipForConditionalGeneration.from_pretrained(model_name, torch_dtype=torch.float16).to("cuda")
def load_image(self, image_path):
if image_path.startswith('http'):
return Image.open(requests.get(image_path, stream=True).raw).convert('RGB')
else:
return Image.open(image_path).convert('RGB')
def generate_caption(self, image, conditional_text="a photography of"):
if conditional_text:
inputs = self.processor(image, conditional_text, return_tensors="pt").to("cuda", torch.float16)
else:
inputs = self.processor(image, return_tensors="pt").to("cuda", torch.float16)
out = self.model.generate(**inputs)
return self.processor.decode(out[0], skip_special_tokens=True)