Skip to content

Commit c26bc23

Browse files
author
matt3o
committed
add clipseg node
1 parent 84d25b9 commit c26bc23

1 file changed

Lines changed: 82 additions & 1 deletion

File tree

essentials.py

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ def INPUT_TYPES(s):
415415
CATEGORY = "essentials"
416416

417417
def execute(self, mask, amount):
418-
size = int(6 * amount +1)
418+
size = int(6 * amount + 1)
419419
if size % 2 == 0:
420420
size+= 1
421421

@@ -1905,6 +1905,81 @@ def execute(self, image_1, image_2, method, image_3=None, image_4=None, image_5=
19051905

19061906
return (out,)
19071907

1908+
class LoadCLIPSegModels:
1909+
@classmethod
1910+
def INPUT_TYPES(s):
1911+
return {
1912+
"required": {},
1913+
}
1914+
1915+
RETURN_TYPES = ("CLIP_SEG",)
1916+
FUNCTION = "execute"
1917+
CATEGORY = "essentials"
1918+
1919+
def execute(self):
1920+
from transformers import CLIPSegProcessor, CLIPSegForImageSegmentation
1921+
processor = CLIPSegProcessor.from_pretrained("CIDAS/clipseg-rd64-refined")
1922+
model = CLIPSegForImageSegmentation.from_pretrained("CIDAS/clipseg-rd64-refined")
1923+
1924+
return ((processor, model),)
1925+
1926+
class ApplyCLIPSeg:
1927+
@classmethod
1928+
def INPUT_TYPES(s):
1929+
return {
1930+
"required": {
1931+
"image": ("IMAGE",),
1932+
"clip_seg": ("CLIP_SEG",),
1933+
"prompt": ("STRING", { "multiline": False, "default": "" }),
1934+
"threshold": ("FLOAT", { "default": 0.4, "min": 0.0, "max": 1.0, "step": 0.05 }),
1935+
"smooth": ("INT", { "default": 9, "min": 0, "max": 32, "step": 1 }),
1936+
"dilate": ("INT", { "default": 0, "min": -32, "max": 32, "step": 1 }),
1937+
"blur": ("INT", { "default": 0, "min": 0, "max": 64, "step": 1 }),
1938+
},
1939+
}
1940+
1941+
RETURN_TYPES = ("MASK",)
1942+
FUNCTION = "execute"
1943+
CATEGORY = "essentials"
1944+
1945+
def execute(self, image, clip_seg, prompt, threshold, smooth, dilate, blur):
1946+
processor, model = clip_seg
1947+
1948+
imagenp = image.mul(255).clamp(0, 255).byte().cpu().numpy()
1949+
1950+
outputs = []
1951+
for i in imagenp:
1952+
inputs = processor(text=prompt, images=[i], return_tensors="pt")
1953+
out = model(**inputs)
1954+
out = out.logits.unsqueeze(1)
1955+
out = torch.sigmoid(out[0][0])
1956+
out = (out > threshold)
1957+
outputs.append(out)
1958+
1959+
del imagenp
1960+
1961+
outputs = torch.stack(outputs, dim=0)
1962+
1963+
if smooth > 0:
1964+
if smooth % 2 == 0:
1965+
smooth += 1
1966+
outputs = T.functional.gaussian_blur(outputs, smooth)
1967+
1968+
outputs = outputs.float()
1969+
1970+
if dilate != 0:
1971+
outputs = expand_mask(outputs, dilate, True)
1972+
1973+
if blur > 0:
1974+
if blur % 2 == 0:
1975+
blur += 1
1976+
outputs = T.functional.gaussian_blur(outputs, blur)
1977+
1978+
# resize to original size
1979+
outputs = F.interpolate(outputs.unsqueeze(1), size=(image.shape[1], image.shape[2]), mode='bicubic').squeeze(1)
1980+
1981+
return (outputs,)
1982+
19081983
NODE_CLASS_MAPPINGS = {
19091984
"GetImageSize+": GetImageSize,
19101985

@@ -1959,6 +2034,9 @@ def execute(self, image_1, image_2, method, image_3=None, image_4=None, image_5=
19592034
"ConditioningCombineMultiple+": ConditioningCombineMultiple,
19602035
"ImageBatchMultiple+": ImageBatchMultiple,
19612036

2037+
"LoadCLIPSegModels+": LoadCLIPSegModels,
2038+
"ApplyCLIPSeg+": ApplyCLIPSeg,
2039+
19622040
#"NoiseFromImage~": NoiseFromImage,
19632041
}
19642042

@@ -2016,5 +2094,8 @@ def execute(self, image_1, image_2, method, image_3=None, image_4=None, image_5=
20162094
"ConditioningCombineMultiple+": "🔧 Conditionings Combine Multiple ",
20172095
"ImageBatchMultiple+": "🔧 Images Batch Multiple",
20182096

2097+
"LoadCLIPSegModels+": "🔧 Load CLIPSeg Models",
2098+
"ApplyCLIPSeg+": "🔧 Apply CLIPSeg",
2099+
20192100
#"NoiseFromImage~": "🔧 Noise From Image",
20202101
}

0 commit comments

Comments
 (0)