# Documentation - Class name: MiDaS_Background_Foreground_Removal - Category: WAS Suite/Image/AI - Output node: False - Repo Ref: https://github.com/WASasquatch/was-node-suite-comfyui 该节点使用MiDaS模型从图像中估计深度,并根据用户输入移除背景或前景,增强图像的视觉清晰度和焦点。 # Input types ## Required - image - 源图像,从中估计深度并移除背景或前景。 - Comfy dtype: IMAGE - Python dtype: PIL.Image - midas_model - 指定用于深度估计的MiDaS模型的大小,较大的模型通常能提供更准确的结果,但需要更多的计算资源。 - Comfy dtype: COMBO[ ['DPT_Large', 'DPT_Hybrid', 'DPT_Small' ]] - Python dtype: str - remove - 指示应从图像中移除背景还是前景,影响输出的构图。 - Comfy dtype: COMBO[ ['background', 'foreground' ]] - Python dtype: str ## Optional - use_cpu - 决定是否使用CPU进行处理。卸载到GPU通常更快,但需要兼容的硬件。 - Comfy dtype: COMBO[ ['false', 'true' ]] - Python dtype: str - threshold - 对深度图应用阈值,可以细化移除元素与图像其余部分的分离。 - Comfy dtype: COMBO[ ['false', 'true' ]] - Python dtype: str - threshold_low - 设置深度值阈值范围的下限,影响分割的精度。 - Comfy dtype: FLOAT - Python dtype: float - threshold_mid - 定义阈值范围的中点,进一步调整保留和移除的图像部分之间的过渡。 - Comfy dtype: FLOAT - Python dtype: float - threshold_high - 建立阈值范围的上限,这可以影响移除过程中图像最深处的处理方式。 - Comfy dtype: FLOAT - Python dtype: float - smoothing - 控制应用于深度图的平滑程度,这有助于减少最终输出中的噪声和伪影。 - Comfy dtype: FLOAT - Python dtype: float - background_red - 设置用于填充移除区域的背景颜色的红色分量,影响结果图像的视觉外观。 - Comfy dtype: INT - Python dtype: int - background_green - 确定背景颜色的绿色分量,有助于构成移除元素区域的整体色彩方案。 - Comfy dtype: INT - Python dtype: int - background_blue - 指定背景颜色的蓝色分量,用于在编辑图像中实现期望的色彩平衡。 - Comfy dtype: INT - Python dtype: int # Output types - result_image - 处理后的图像,已移除指定的背景或前景元素,可供进一步使用或分析。 - Comfy dtype: IMAGE - Python dtype: PIL.Image - depth_map - 从输入图像派生出的深度图,视觉上表示场景中的估计距离,并在内部用于移除过程。 - Comfy dtype: IMAGE - Python dtype: PIL.Image # Usage tips - Infra type: GPU # Source code ``` class MiDaS_Background_Foreground_Removal: def __init__(self): self.midas_dir = os.path.join(MODELS_DIR, 'midas') @classmethod def INPUT_TYPES(cls): return {'required': {'image': ('IMAGE',), 'use_cpu': (['false', 'true'],), 'midas_model': (['DPT_Large', 'DPT_Hybrid', 'DPT_Small'],), 'remove': (['background', 'foregroud'],), 'threshold': (['false', 'true'],), 'threshold_low': ('FLOAT', {'default': 10, 'min': 0, 'max': 255, 'step': 1}), 'threshold_mid': ('FLOAT', {'default': 200, 'min': 0, 'max': 255, 'step': 1}), 'threshold_high': ('FLOAT', {'default': 210, 'min': 0, 'max': 255, 'step': 1}), 'smoothing': ('FLOAT', {'default': 0.25, 'min': 0.0, 'max': 16.0, 'step': 0.01}), 'background_red': ('INT', {'default': 0, 'min': 0, 'max': 255, 'step': 1}), 'background_green': ('INT', {'default': 0, 'min': 0, 'max': 255, 'step': 1}), 'background_blue': ('INT', {'default': 0, 'min': 0, 'max': 255, 'step': 1})}} RETURN_TYPES = ('IMAGE', 'IMAGE') FUNCTION = 'midas_remove' CATEGORY = 'WAS Suite/Image/AI' def midas_remove(self, image, midas_model, use_cpu='false', remove='background', threshold='false', threshold_low=0, threshold_mid=127, threshold_high=255, smoothing=0.25, background_red=0, background_green=0, background_blue=0): global MIDAS_INSTALLED if not MIDAS_INSTALLED: self.install_midas() import cv2 as cv i = 255.0 * image.cpu().numpy().squeeze() img = i img_original = tensor2pil(image).convert('RGB') cstr('Downloading and loading MiDaS Model...').msg.print() torch.hub.set_dir(self.midas_dir) midas = torch.hub.load('intel-isl/MiDaS', midas_model, trust_repo=True) device = torch.device('cuda') if torch.cuda.is_available() and use_cpu == 'false' else torch.device('cpu') cstr(f'MiDaS is using device: {device}').msg.print() midas.to(device).eval() midas_transforms = torch.hub.load('intel-isl/MiDaS', 'transforms') if midas_model == 'DPT_Large' or midas_model == 'DPT_Hybrid': transform = midas_transforms.dpt_transform else: transform = midas_transforms.small_transform img = cv.cvtColor(img, cv.COLOR_BGR2RGB) input_batch = transform(img).to(device) cstr('Approximating depth from image.').msg.print() with torch.no_grad(): prediction = midas(input_batch) prediction = torch.nn.functional.interpolate(prediction.unsqueeze(1), size=img.shape[:2], mode='bicubic', align_corners=False).squeeze() if remove == 'foreground': depth = 255 - prediction.cpu().numpy().astype(np.uint8) depth = depth.astype(np.float32) else: depth = prediction.cpu().numpy().astype(np.float32) depth = depth * 255 / np.max(depth) / 255 depth = Image.fromarray(np.uint8(depth * 255)) if threshold == 'true': levels = self.AdjustLevels(threshold_low, threshold_mid, threshold_high) depth = levels.adjust(depth.convert('RGB')).convert('L') if smoothing > 0: depth = depth.filter(ImageFilter.GaussianBlur(radius=smoothing)) depth = depth.resize(img_original.size).convert('L') background_red = int(background_red) if isinstance(background_red, (int, float)) else 0 background_green = int(background_green) if isinstance(background_green, (int, float)) else 0 background_blue = int(background_blue) if isinstance(background_blue, (int, float)) else 0 background_color = (background_red, background_green, background_blue) background = Image.new(mode='RGB', size=img_original.size, color=background_color) result_img = Image.composite(img_original, background, depth) del midas, device, midas_transforms del transform, img, img_original, input_batch, prediction return (pil2tensor(result_img), pil2tensor(depth.convert('RGB'))) class AdjustLevels: def __init__(self, min_level, mid_level, max_level): self.min_level = min_level self.mid_level = mid_level self.max_level = max_level def adjust(self, im): im_arr = np.array(im) im_arr[im_arr < self.min_level] = self.min_level im_arr = (im_arr - self.min_level) * (255 / (self.max_level - self.min_level)) im_arr[im_arr < 0] = 0 im_arr[im_arr > 255] = 255 im_arr = im_arr.astype(np.uint8) im = Image.fromarray(im_arr) im = ImageOps.autocontrast(im, cutoff=self.max_level) return im def install_midas(self): global MIDAS_INSTALLED if 'timm' not in packages(): install_package('timm') MIDAS_INSTALLED = True ```