import sys, os sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "services", "recolor")) import numpy as np import cv2 from PIL import Image from fabric_recolor.masks import _silhouette_bands from fabric_recolor.labcolor import rgb_to_lab for name, mp, kp in [ ("detail", "data/media/assets/20/20282cb1bd8a58596050b99b9f29e079145a7bcc45ea46b8523ae2389801fbdc.png", "data/media/assets/20/20282cb1bd8a58596050b99b9f29e079145a7bcc45ea46b8523ae2389801fbdc.mask.png"), ("packshot_front", "data/media/assets/79/7987376a67865864247263e5028a83950a2fd900740bbe339fab1ff8e6b3fbb2.png", "data/media/assets/79/7987376a67865864247263e5028a83950a2fd900740bbe339fab1ff8e6b3fbb2.mask.png"), ("hero", "data/media/assets/f0/f06282d9ba621d137d7c978cf931792ffbcb6b5c9764cf94e964f83ded13ddcf.png", "data/media/assets/f0/f06282d9ba621d137d7c978cf931792ffbcb6b5c9764cf94e964f83ded13ddcf.mask.png"), ]: rgb = np.asarray(Image.open(mp).convert("RGB"), dtype=np.uint8) mask = np.asarray(Image.open(kp).convert("L"), dtype=np.uint8) if mask.shape != rgb.shape[:2]: mask = cv2.resize(mask, (rgb.shape[1], rgb.shape[0]), interpolation=cv2.INTER_NEAREST) mb = (mask > 128).astype(np.uint8) band, defect = _silhouette_bands(mb, 6) lab = rgb_to_lab(rgb) med = np.median(lab[mb > 0], axis=0) h, w = mb.shape # hull i jego otoczenie cnts, _ = cv2.findContours(mb, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) hull = np.zeros_like(mb) for c in cnts: cv2.fillPoly(hull, [cv2.convexHull(c)], 1) outside = ((1 - mb) & (1 - hull)).astype(np.uint8) # tlo poza otoczka n, lab_c, stats, _ = cv2.connectedComponentsWithStats(defect, connectivity=8) print(f"== {name}") k3 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) for i in range(1, n): area = stats[i, cv2.CC_STAT_AREA] if area < 5000: continue comp = (lab_c == i).astype(np.uint8) rim = cv2.dilate(comp, k3) & (1 - comp) # piksele sasiadujace to_mask = int((rim & mb).sum()) to_outside = int((rim & outside).sum()) to_defect = int(rim.sum()) - to_mask - to_outside # inne defekty dl = np.linalg.norm(lab[comp > 0].mean(axis=0) - med) ys, xs = np.nonzero(comp) edge = xs.min() == 0 or xs.max() == w - 1 or ys.min() == 0 or ys.max() == h - 1 print(f" defekt {i}: area={area} ({100*area/mb.size:.2f}%) dE={dl:.1f} krawedz={edge} rim: maska={to_mask} tlo={to_outside} ({100*to_mask/max(1,to_mask+to_outside):.0f}% przylega do maski)")