Implement Nova Farma S1 Max: Layered terrain, water mechanics, Y-sorting, and asset cleanup
This commit is contained in:
75
scripts/utils/clean_and_move_image.py
Normal file
75
scripts/utils/clean_and_move_image.py
Normal file
@@ -0,0 +1,75 @@
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
import os
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
def clean_and_save(input_path, output_path):
|
||||
# Ensure directory exists
|
||||
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
||||
|
||||
print(f"Processing: {input_path}")
|
||||
|
||||
# Read image
|
||||
img = cv2.imread(input_path)
|
||||
if img is None:
|
||||
print(f"Error: Could not read {input_path}")
|
||||
sys.exit(1)
|
||||
|
||||
# Convert to RGBA
|
||||
img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
|
||||
|
||||
# Convert to HSV for better color segmentation
|
||||
hsv = cv2.cvtColor(img[:,:,:3], cv2.COLOR_BGR2HSV)
|
||||
|
||||
# Define Magenta range in HSV
|
||||
# Magenta is around 300 degrees. OpenCV Hue is 0-179 (degrees/2). So 300/2 = 150.
|
||||
# Range: 140 - 160 approx.
|
||||
# We want to catch the solid pink background.
|
||||
|
||||
# Lower and Upper bounds for Magenta/Pink
|
||||
# Hue: 140-170, Saturation: > 50, Value: > 50
|
||||
lower_magenta = np.array([140, 50, 50])
|
||||
upper_magenta = np.array([170, 255, 255])
|
||||
|
||||
mask = cv2.inRange(hsv, lower_magenta, upper_magenta)
|
||||
|
||||
# Invert mask (keep non-magenta)
|
||||
mask_inv = cv2.bitwise_not(mask)
|
||||
|
||||
# Update alpha channel
|
||||
# Where mask is 255 (magenta), alpha should be 0.
|
||||
# We can just set the alpha channel to mask_inv directly.
|
||||
# However, to avoid hard edges, we might want to erode/dilate, but for pixel/vector props hard cut is usually fine.
|
||||
|
||||
# Let's perform a small morphological operation to remove pink noise on edges if any
|
||||
kernel = np.ones((1,1), np.uint8)
|
||||
mask_inv = cv2.morphologyEx(mask_inv, cv2.MORPH_OPEN, kernel)
|
||||
|
||||
b, g, r, a = cv2.split(img)
|
||||
img = cv2.merge((b, g, r, mask_inv))
|
||||
|
||||
# Crop to content (optional but good for assets)
|
||||
# Find bounding box of non-transparent area
|
||||
coords = cv2.findNonZero(mask_inv)
|
||||
if coords is not None:
|
||||
x, y, w, h = cv2.boundingRect(coords)
|
||||
# Add 1px padding if possible
|
||||
x = max(0, x-1)
|
||||
y = max(0, y-1)
|
||||
w = min(img.shape[1]-x, w+2)
|
||||
h = min(img.shape[0]-y, h+2)
|
||||
img = img[y:y+h, x:x+w]
|
||||
|
||||
# Save
|
||||
cv2.imwrite(output_path, img)
|
||||
print(f"Successfully saved cleaned image to {output_path}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='Remove magenta background and save.')
|
||||
parser.add_argument('input', help='Input file path')
|
||||
parser.add_argument('output', help='Output file path')
|
||||
args = parser.parse_args()
|
||||
|
||||
clean_and_save(args.input, args.output)
|
||||
Reference in New Issue
Block a user