from PIL import Image
import numpy as np
from collections import deque
src=r"C:\Users\ELR17\AppData\Local\Temp\claude\e--GDRIVE-SERVEUR-ET-PRODUCTION-WEB-2025-REBIRTH-BIG-EGG\ed83a6e2-abd6-4841-b972-8de373593d99\images\1.png"
im=np.asarray(Image.open(src).convert("RGB")).astype(int)
boxes={"dock_rat":(25,185,305,535),"barnacle_brute":(310,15,765,535),"loaded_dice_crab":(740,190,1150,535),
"powder_gull":(1150,70,1440,535),"siren_dancer":(15,550,440,1082),"platform_mimic":(445,630,840,1065),"gab_le_crab":(895,530,1425,1080)}
out="tools/meshy/meshy_output/old_port/crops"
reg=im[280:470,1140:1175]; sat=reg.max(axis=2)-reg.min(axis=2); reg[sat>45]=im[5,5]
def dilate(m,n):
    for _ in range(n):
        p=m.copy(); p[1:]|=m[:-1]; p[:-1]|=m[1:]; p[:,1:]|=m[:,:-1]; p[:,:-1]|=m[:,1:]; m=p
    return m
def erode(m,n): return ~dilate(~m,n)
def label(m):
    lab=np.zeros(m.shape,int); h,w=m.shape; n=0; sizes=[0]
    for y,x in zip(*np.nonzero(m)):
        if lab[y,x]: continue
        n+=1; q=deque([(y,x)]); lab[y,x]=n; s=0
        while q:
            cy,cx=q.popleft(); s+=1
            for dy,dx in ((1,0),(-1,0),(0,1),(0,-1)):
                ny,nx=cy+dy,cx+dx
                if 0<=ny<h and 0<=nx<w and m[ny,nx] and not lab[ny,nx]:
                    lab[ny,nx]=n; q.append((ny,nx))
        sizes.append(s)
    return lab,sizes
def fill_holes(m):
    outside=np.zeros_like(m); h,w=m.shape; q=deque()
    for y in range(h):
        for x in (0,w-1):
            if not m[y,x] and not outside[y,x]: outside[y,x]=1; q.append((y,x))
    for x in range(w):
        for y in (0,h-1):
            if not m[y,x] and not outside[y,x]: outside[y,x]=1; q.append((y,x))
    while q:
        cy,cx=q.popleft()
        for dy,dx in ((1,0),(-1,0),(0,1),(0,-1)):
            ny,nx=cy+dy,cx+dx
            if 0<=ny<h and 0<=nx<w and not m[ny,nx] and not outside[ny,nx]: outside[ny,nx]=1; q.append((ny,nx))
    return ~outside.astype(bool)
for k,(x0,y0,x1,y1) in boxes.items():
    c=im[y0:y1,x0:x1].copy()
    border=np.concatenate([c[0],c[-1],c[:,0],c[:,-1]]); lb=np.median(border,axis=0)
    fg=np.abs(c-lb).sum(axis=2)>40
    fg=erode(dilate(fg,3),3)
    lab,sizes=label(fg); sizes=np.array(sizes); big=sizes[1:].max()
    keep=np.zeros_like(fg); H,W=fg.shape
    for i in range(1,len(sizes)):
        s=sizes[i]
        if s<0.03*big: continue
        ys,xs=np.nonzero(lab==i)
        touches=xs.min()==0 or xs.max()==W-1 or ys.min()==0
        if s==big or not touches: keep|=lab==i
    keep=fill_holes(dilate(keep,3))
    c[~keep]=lb
    ys,xs=np.nonzero(keep); c=c[ys.min():ys.max()+1,xs.min():xs.max()+1]
    h,w=c.shape[:2]; s=int(max(w,h)*1.12)
    sq=np.tile(lb,(s,s,1)); sq[(s-h)//2:(s-h)//2+h,(s-w)//2:(s-w)//2+w]=c
    Image.fromarray(sq.astype(np.uint8)).resize((1024,1024),Image.LANCZOS).save(f"{out}/{k}.png")
    print(k,"blobs kept", int(keep.sum()))
bg=tuple(im[5,5].tolist())
sheet=Image.new("RGB",(7*300,300),bg)
for i,k in enumerate(boxes): sheet.paste(Image.open(f"{out}/{k}.png").resize((300,300)),(i*300,0))
sheet.save(f"{out}/_sheet.png")
