RacingDemo / src /extract.py
Vlad Bastina
merge
10877f8
import cv2
import numpy as np
# === Inputs ===
background = cv2.imread('assets/BACKGROUND.png') # Background with circle
input_image = cv2.imread('frame_00_00_31_738.png') # Full input image
bbox = (495, 595, 801, 820) # Normalized (0–1000) format
# Get input image size
img_height, img_width = input_image.shape[:2]
# Convert normalized bbox to absolute pixel coordinates
y_min = int(bbox[0] / 1000.0 * img_height)
x_min = int(bbox[1] / 1000.0 * img_width)
y_max = int(bbox[2] / 1000.0 * img_height)
x_max = int(bbox[3] / 1000.0 * img_width)
# Bounding box size and center
bbox_w = x_max - x_min
bbox_h = y_max - y_min
bbox_center_x = x_min + bbox_w // 2
bbox_center_y = y_min + bbox_h // 2
# Target circle (on background)
circle_center = (296, 126)
circle_radius = 77
circle_diameter = 2 * circle_radius
# === 1. Compute scale so the bbox fits inside the circle ===
scale = min(circle_diameter / bbox_w, circle_diameter / bbox_h)
# === 2. Resize the entire input image ===
new_width = int(img_width * scale)
new_height = int(img_height * scale)
resized_image = cv2.resize(input_image, (new_width, new_height))
# === 3. Compute new center of the bbox after scaling ===
new_bbox_center_x = int(bbox_center_x * scale)
new_bbox_center_y = int(bbox_center_y * scale)
# === 4. Compute offset so that bbox center aligns with circle center ===
offset_x = circle_center[0] - new_bbox_center_x
offset_y = circle_center[1] - new_bbox_center_y
# === 5. Paste resized image onto background ===
# Create a blank canvas same size as background
canvas = np.zeros_like(background)
# Compute region where image will be placed
start_x = max(offset_x, 0)
start_y = max(offset_y, 0)
end_x = min(start_x + new_width, background.shape[1])
end_y = min(start_y + new_height, background.shape[0])
src_start_x = max(-offset_x, 0)
src_start_y = max(-offset_y, 0)
# Copy region from resized image to canvas
canvas[start_y:end_y, start_x:end_x] = resized_image[src_start_y:src_start_y + (end_y - start_y), src_start_x:src_start_x + (end_x - start_x)]
mask = cv2.imread('circle_mask.png', cv2.IMREAD_GRAYSCALE)
mask = cv2.resize(mask, (background.shape[1], background.shape[0])) # Ensure same size
# Blend entire image (for use outside circle)
alpha = 0.3
beta = 1.0 - alpha
blended = cv2.addWeighted(canvas, alpha, background, beta, 0)
# Create 3-channel version of mask
mask_3c = cv2.merge([mask, mask, mask])
# Create inverse mask (inside circle)
inv_mask = cv2.bitwise_not(mask_3c)
# Apply blended background where mask is white (outside the circle)
outside = cv2.bitwise_and(blended, mask_3c)
# Apply original canvas (input image) where mask is black (inside the circle)
inside = cv2.bitwise_and(canvas, inv_mask)
# Combine both
combined = cv2.add(outside, inside)
# === 6. Save result ===
cv2.imwrite('output.png', combined)