diff --git a/README.MD b/README.MD index 1ce1c57..d31a090 100644 --- a/README.MD +++ b/README.MD @@ -17,6 +17,7 @@ Nodes are divided into 5 groups according to their functions: LayerStyle, LayerC ## Update **If the dependency package error after updating, please reinstall the relevant dependency packages. for details, please refer to [here](https://github.com/chflame163/ComfyUI_LayerStyle/issues/5). +* Commit [ImageAutoCrop](#ImageAutoCrop) node, which is designed to generate image materials for training models. * Commit [ImageScaleByAspectRatio](#ImageScaleByAspectRatio) node, it can be scaled image or mask according to frame ratio. * Fix the bug of color gradation in [LUT Apply](#LUT) node rendering, and this node now support for log color space. *Please load the dedicated log lut file for the log color space image. * Commit [CreateGradientMask](#CreateGradientMask) node. Commit [LayerImageTransform](#LayerImageTransform) and [LayerMaskTransform](#LayerMaskTransform) nodes. @@ -596,6 +597,34 @@ Node options: ![image](image/image_channel_merge_node.png) * mode: Channel mode, include RGBA, YCbCr, LAB adn HSV. +### ImageAutoCrop +![image](image/image_auto_crop_example.png) +Automatically cutout and crop the image according to the mask. it can specify the background color, aspect ratio, and size for output image. this node is designed to generate the image materials for training models. +*Please refer to the model installation methods for [SegmentAnythingUltra](#SegmentAnythingUltra) and [RemBgUltra](#RemBgUltra). + + +Node options: +![image](image/image_auto_crop_node.png) +* background_color4: The background color. +* aspect_ratio: Here are several common frame ratios provided. alternatively, you can choose "original" to keep original ratio or customize the ratio using "custom". +* proportional_width: Proportional width. if the aspect ratio option is not "custom", this setting will be ignored. +* proportional_height: Proportional height. if the aspect ratio option is not "custom", this setting will be ignored. +* scale_by_longest_side: Allow scaling by long edge size. +* longest_side: When the scale_by_longest_side is set to True, this will be used this value to the long edge of the image. when the original_size have input, this setting will be ignored. +* detect: Detection method, min_bounding_rect is the minimum bounding rectangle, max_inscribed_rect is the maximum inscribed rectangle. +* border_reserve: Keep the border. expand the cutting range beyond the detected mask body area. +* ultra_detail_range: Mask edge ultra fine processing range, 0 is not processed, which can save generation time. +* matting_method: The method of generate masks. There are two methods available: Segment Anything and RMBG 1.4. RMBG 1.4 runs faster. +* sam_model: Select the SAM model used by Segment Anything here. +* grounding_dino_model: Select the Grounding_Dino model used by Segment Anything here. +* sam_threshold: The threshold for Segment Anything. +* sam_prompt: The prompt for Segment Anything. + +Output: +cropped_image: Crop and replace the background image. +box_preview: Crop position preview + + ### GetImageSize ![image](image/get_image_size_node.png) Obtain the width and height of the image. diff --git a/README_CN.MD b/README_CN.MD index 95908db..599b78d 100644 --- a/README_CN.MD +++ b/README_CN.MD @@ -13,6 +13,7 @@ ## 更新说明 **如果本插件更新后出现依赖包错误,请重新安装相关依赖包。详情见[这里](https://github.com/chflame163/ComfyUI_LayerStyle/issues/5)。 +* 添加 [ImageAutoCrop](#ImageAutoCrop) 节点, 这个节点是为生成训练模型的图片素材而设计的。 * 添加 [ImageScaleByAspectRatio](#ImageScaleByAspectRatio) 节点, 可按画幅比例缩放图像。 * 改正 [LUT Apply](#LUT) 节点渲染出现色阶的bug, 并增加log色彩空间支持。*log色彩空间图片请加载专门的log lut。 * 添加[CreateGradientMask](#CreateGradientMask) 节点。添加 [LayerImageTransform](#LayerImageTransform) 和 [LayerMaskTransform](#LayerMaskTransform) 节点。 @@ -583,6 +584,34 @@ ![image](image/image_channel_merge_node.png) * mode: 通道模式。包含RGBA, YCbCr, LAB和HSV。 +### ImageAutoCrop +![image](image/image_auto_crop_example.png) +自动抠图并按照遮罩裁切图片。可指定生成图片的背景颜色、长宽比和大小。这个节点是为生成训练模型的图片素材而设计的。 +*请参照 [SegmentAnythingUltra](#SegmentAnythingUltra) 和 [RemBgUltra](#RemBgUltra) 节点的模型安装方法安装模型。 + + +节点选项说明: +![image](image/image_auto_crop_node.png) +* background_color4: 背景颜色。 +* aspect_ratio: 输出的宽高比。这里提供了常见的画幅比例, "custom"为自定义比例。 +* proportional_width: 比例宽。如果aspect_ratio选项不是"custom",此处设置将被忽略。 +* proportional_height: 比例高。如果aspect_ratio选项不是"custom",此处设置将被忽略。 +* scale_by_longest_side: 允许按长边尺寸缩放。 +* longest_side: scale_by_longest_side被设置为True时,此项将作为是图像长边的长度。 +* detect: 探测方法,min_bounding_rect是最小外接矩形, max_inscribed_rect是最大内接矩形。 +* border_reserve: 保留边框。在探测到的遮罩主体区域之外扩展裁切范围。 +* ultra_detail_range: 遮罩边缘超精细处理范围,0为不处理,可以节省生成时间。 +* matting_method: 生成遮罩的方法。有Segment Anything和 RMBG 1.4两种方法。RMBG 1.4运行速度更快。 +* sam_model: 此处选择Segment Anything所使用的sam模型。 +* grounding_dino_model: 此处选择Segment Anything所使用的grounding_dino模型。 +* sam_threshold: Segment Anything的阈值。 +* sam_prompt: Segment Anything的提示词。 + +输出: +cropped_image: 裁切并更换背景后的图像。 +box_preview: 裁切位置预览。 + + ### GetImageSize ![image](image/get_image_size_node.png) 获取图片的宽度和高度。 diff --git a/image/image_auto_crop_example.png b/image/image_auto_crop_example.png new file mode 100644 index 0000000..b529ff1 Binary files /dev/null and b/image/image_auto_crop_example.png differ diff --git a/image/image_auto_crop_node.png b/image/image_auto_crop_node.png new file mode 100644 index 0000000..05e4fad Binary files /dev/null and b/image/image_auto_crop_node.png differ diff --git a/py/image_auto_crop.py b/py/image_auto_crop.py index d4d7c4b..727b9ec 100644 --- a/py/image_auto_crop.py +++ b/py/image_auto_crop.py @@ -1,4 +1,5 @@ from .imagefunc import * +from .segment_anything_func import * NODE_NAME = 'ImageAutoCrop' @@ -9,20 +10,26 @@ class ImageAutoCrop: @classmethod def INPUT_TYPES(self): + matting_method_list = ['RMBG 1.4', 'SegmentAnything'] detect_mode = ['min_bounding_rect', 'max_inscribed_rect'] ratio_list = ['1:1', '3:2', '4:3', '16:9', '2:3', '3:4', '9:16', 'custom'] return { "required": { "image": ("IMAGE", ), # - "detect": (detect_mode,), - "border_reserve": ("INT", {"default": 100, "min": -9999, "max": 9999, "step": 1}), + "background_color": ("STRING", {"default": "#FFFFFF"}), # 鑳屾櫙棰滆壊 "aspect_ratio": (ratio_list,), "proportional_width": ("INT", {"default": 2, "min": 1, "max": 999, "step": 1}), "proportional_height": ("INT", {"default": 1, "min": 1, "max": 999, "step": 1}), - "background_color": ("STRING", {"default": "#FFFFFF"}), # 鑳屾櫙棰滆壊 - "edge_ultra_detail": ("BOOLEAN", {"default": False}), # 鏄惁淇竟缂� - "scale_to_longest_side": ("BOOLEAN", {"default": False}), # 鏄惁鎸夐暱杈圭缉鏀� + "scale_to_longest_side": ("BOOLEAN", {"default": True}), # 鏄惁鎸夐暱杈圭缉鏀� "longest_side": ("INT", {"default": 1024, "min": 4, "max": 999999, "step": 1}), + "detect": (detect_mode,), + "border_reserve": ("INT", {"default": 100, "min": -9999, "max": 9999, "step": 1}), + "ultra_detail_range": ("INT", {"default": 0, "min": 0, "max": 256, "step": 1}), + "matting_method": (matting_method_list,), + "sam_model": (list_sam_model(),), + "grounding_dino_model": (list_groundingdino_model(),), + "sam_threshold": ("FLOAT", {"default": 0.3, "min": 0, "max": 1.0, "step": 0.01}), + "sam_prompt": ("STRING", {"default": "subject"}), }, "optional": { } @@ -35,8 +42,9 @@ class ImageAutoCrop: OUTPUT_NODE = True def image_auto_crop(self, image, detect, border_reserve, aspect_ratio, proportional_width, proportional_height, - background_color, edge_ultra_detail, scale_to_longest_side, longest_side - ): + background_color, ultra_detail_range, scale_to_longest_side, longest_side, + matting_method, sam_model, grounding_dino_model, sam_threshold, sam_prompt + ): ret_images = [] ret_box_previews = [] @@ -66,9 +74,17 @@ class ImageAutoCrop: if len(input_masks) > 0: _mask = input_masks[i] else: - _mask = RMBG(_image) - if edge_ultra_detail: - _mask = tensor2pil(mask_edge_detail(input_images[i], pil2tensor(_mask), 8, 0.01, 0.99)) + if matting_method == 'SegmentAnything': + sam_model = load_sam_model(sam_model) + dino_model = load_groundingdino_model(grounding_dino_model) + item = _image.convert('RGBA') + boxes = groundingdino_predict(dino_model, item, sam_prompt, sam_threshold) + (_, _mask) = sam_segment(sam_model, item, boxes) + _mask = mask2image(_mask[0]) + else: + _mask = RMBG(_image) + if ultra_detail_range: + _mask = tensor2pil(mask_edge_detail(input_images[i], pil2tensor(_mask), ultra_detail_range, 0.01, 0.99)) bluredmask = gaussian_blur(_mask, 20).convert('L') x = 0 y = 0 @@ -102,7 +118,7 @@ class ImageAutoCrop: target_width, target_height = calculate_side_by_ratio(crop_box[2], crop_box[3], ratio, longest_side=side_limit) _canvas = Image.new('RGB', size=(canvas_width, canvas_height), color=background_color) - if edge_ultra_detail: + if ultra_detail_range: _image = pixel_spread(_image, _mask) _canvas.paste(_image, box=(x_offset, y_offset), mask=_mask.convert('L')) preview_image = Image.new('RGB', size=(canvas_width, canvas_height), color='gray') diff --git a/py/imagefunc.py b/py/imagefunc.py index 39f8db3..b9fbbae 100644 --- a/py/imagefunc.py +++ b/py/imagefunc.py @@ -41,8 +41,7 @@ def log(message:str, message_type:str='info'): try: from cv2.ximgproc import guidedFilter except ImportError: - log(f'Dependency package error -> Unable import "guidedFilter", please reinstall "opencv-contrib-python', message_type='error') - + log(f'Dependency package error -> Unable import "cv2.ximgproc", please reinstall "opencv-contrib-python', message_type='error') '''Converter'''