84 lines
3.1 KiB
Python
84 lines
3.1 KiB
Python
import cv2
|
|
import numpy as np
|
|
import os
|
|
|
|
def trim_walls_manual():
|
|
src_path = '/Users/davidkotnik/.gemini/antigravity/brain/07019d04-a214-43ab-9565-86f4e8f17e5b/uploaded_media_1769607894587.jpg'
|
|
|
|
print(f"Loading {src_path}")
|
|
img = cv2.imread(src_path)
|
|
if img is None: return
|
|
|
|
# 1. Basic GrabCut to remove BG
|
|
mask = np.zeros(img.shape[:2], np.uint8)
|
|
bgdModel = np.zeros((1,65),np.float64)
|
|
fgdModel = np.zeros((1,65),np.float64)
|
|
h, w = img.shape[:2]
|
|
cv2.grabCut(img, mask, (10, 10, w-20, h-20), bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)
|
|
mask_final = np.where((mask==2)|(mask==0),0,1).astype('uint8')
|
|
|
|
# 2. MANUAL TRIM
|
|
# The "Wall" problem is mainly on the bottom edges because of the isometric height.
|
|
# We can try to erode the mask from the bottom-left direction?
|
|
# Or simpler: Detect the DARK BROWN/BLACK pixels near the boundary and make them transparent.
|
|
|
|
# Convert to HSV
|
|
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
|
|
|
|
# Define "Wall Shadow" color
|
|
# Walls are very dark. Value < 40 or so.
|
|
is_dark = (hsv[:,:,2] < 50)
|
|
|
|
# And we only care about dark pixels that are currently part of the mask.
|
|
is_part_of_object = (mask_final == 1)
|
|
|
|
# We want to remove dark pixels ONLY if they are on the "outside" or extending downwards.
|
|
# Let's try to remove ALL "Very Dark" pixels that are connected to the mask boundary?
|
|
# No, that might remove internal details.
|
|
|
|
# Let's try aggressive erosion of dark areas.
|
|
# Create a mask of "Walls to Remove" = Dark pixels.
|
|
walls_mask = (is_dark & is_part_of_object).astype(np.uint8)
|
|
|
|
# Morphological Opening to remove noise (thin lines might be outlines, we want blocks)
|
|
walls_mask = cv2.morphologyEx(walls_mask, cv2.MORPH_OPEN, np.ones((5,5), np.uint8))
|
|
|
|
# Subtract walls from main mask
|
|
mask_trimmed = mask_final.copy()
|
|
mask_trimmed[walls_mask == 1] = 0
|
|
|
|
# Verify: Did we eat too much?
|
|
# The pipes drain hole is dark! We must protect the top-right quadrant.
|
|
# Let's define a safe zone (Top 40% of image height + Right 40% of width)
|
|
safe_y = int(h * 0.4)
|
|
# Actually, simpler: just don't touch the top-right area where the pipe is.
|
|
# Let's mask out the top-right from the removal process.
|
|
# Pipe bounding box approx: x > w*0.6, y < h*0.5
|
|
walls_mask[0:int(h*0.5), int(w*0.6):w] = 0
|
|
|
|
# Now re-apply subtraction
|
|
mask_trimmed = mask_final.copy()
|
|
mask_trimmed[walls_mask == 1] = 0
|
|
|
|
# 3. Output
|
|
b, g, r = cv2.split(img)
|
|
alpha = mask_trimmed * 255
|
|
img_rgba = cv2.merge([b, g, r, alpha])
|
|
|
|
# Crop
|
|
coords = cv2.findNonZero(alpha)
|
|
if coords is not None:
|
|
x, y, cw, ch = cv2.boundingRect(coords)
|
|
img_rgba = img_rgba[y:y+ch, x:x+cw]
|
|
|
|
targets = [
|
|
'/Users/davidkotnik/repos/novafarma/main/assets/stream_pipe.png',
|
|
'/Users/davidkotnik/repos/novafarma/assets/DEMO_FAZA1/Environment/stream_pipe.png'
|
|
]
|
|
for t in targets:
|
|
cv2.imwrite(t, img_rgba)
|
|
print(f"Saved {t}")
|
|
|
|
if __name__ == "__main__":
|
|
trim_walls_manual()
|