forked from mercu-lore/BoxBox
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathregion_crop_node.py
More file actions
124 lines (102 loc) · 4.12 KB
/
region_crop_node.py
File metadata and controls
124 lines (102 loc) · 4.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""
Region Crop Node - Nodo che taglia l'immagine secondo le coordinate selezionate
"""
import json
import torch
class RegionCropNode:
"""
Nodo che taglia un'immagine usando le coordinate fornite dal RegionSelectorNode.
"""
def __init__(self):
"""Inizializza il nodo"""
pass
@classmethod
def INPUT_TYPES(cls):
"""
Definisce gli input del nodo.
"""
return {
"required": {
"image": ("IMAGE",),
"box_metadata": ("STRING", {
"default": "",
"multiline": True,
}),
},
"optional": {
"fallback_mode": (["use_full_image", "return_zero", "error"], {
"default": "use_full_image",
}),
}
}
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("cropped_image",)
FUNCTION = "crop_image"
CATEGORY = "image/region"
def crop_image(self, image, box_metadata, fallback_mode="use_full_image"):
"""
Taglia l'immagine secondo le coordinate nel metadata.
Args:
image: Tensor immagine (B, H, W, C)
box_metadata: JSON string con coordinate della regione
fallback_mode: Cosa fare se non ci sono coordinate valide
Returns:
(cropped_image,): Immagine ritagliata
"""
try:
metadata = json.loads(box_metadata) if box_metadata.strip() else {}
except json.JSONDecodeError:
metadata = {}
# Estrai coordinate (x1, x2, y1, y2 sono i lati)
x1 = metadata.get("x1", None)
x2 = metadata.get("x2", None)
y1 = metadata.get("y1", None)
y2 = metadata.get("y2", None)
# Se non c'è selezione
if x1 is None or x2 is None or y1 is None or y2 is None:
if fallback_mode == "use_full_image":
return (image,)
elif fallback_mode == "return_zero":
return (torch.zeros_like(image),)
else:
raise ValueError("No region coordinates provided in metadata")
# Estrai il fattore di scala se la preview era stata scalata
display_scale_factor = metadata.get("displayScaleFactor", 1.0)
if display_scale_factor and display_scale_factor != 1.0:
# Se le coordinate sono state prese da una preview scalata,
# dividi per il fattore di scala per ottenere le coordinate originali
x1 = x1 / display_scale_factor
x2 = x2 / display_scale_factor
y1 = y1 / display_scale_factor
y2 = y2 / display_scale_factor
print(f"[BoxCrop] Scale factor detected: {display_scale_factor}x. Adjusted coordinates.")
# Assicura che le coordinate siano integer
x1 = int(round(x1))
x2 = int(round(x2))
y1 = int(round(y1))
y2 = int(round(y2))
# Estrai dimensioni immagine
batch_size, img_height, img_width, channels = image.shape
# Assicura che x1 < x2 e y1 < y2
x_start = min(x1, x2)
x_end = max(x1, x2)
y_start = min(y1, y2)
y_end = max(y1, y2)
# Calcola coordinate finali con clipping ai bordi
x_start = max(0, min(x_start, img_width - 1))
x_end = max(x_start + 1, min(x_end, img_width))
y_start = max(0, min(y_start, img_height - 1))
y_end = max(y_start + 1, min(y_end, img_height))
# Verifica validità della region
if x_end <= x_start or y_end <= y_start:
if fallback_mode == "use_full_image":
return (image,)
elif fallback_mode == "return_zero":
return (torch.zeros_like(image),)
else:
raise ValueError("Invalid region coordinates: no overlap with image")
# Taglia l'immagine
cropped = image[:, y_start:y_end, x_start:x_end, :]
return (cropped,)
NODE_CLASS_MAPPINGS = {"BoxCrop": RegionCropNode}
NODE_DISPLAY_NAME_MAPPINGS = {"BoxCrop": "✂️ BoxCrop"}