@@ -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+
19081983NODE_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