You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中为Meta AI Segment Anything(SAM)生成透明分割掩码?

问题:为SAM生成透明分割掩码以保留原始图像色彩

我需要为Meta AI的Segment Anything(SAM)生成透明分割掩码,目的是保留分割区域的原始颜色。目前我用sv.MaskAnnotator(color=sv.Color.xyz)来指定掩码颜色,但不知道怎么设置成完全透明,从而让原始图像的颜色透出来。我以YOLOv8生成的边界框作为SAM的输入,相关代码如下:

import numpy as np
import cv2
import supervision as sv
from jupyter_bbox_widget import BBoxWidget

widget = BBoxWidget()

# default_box is going to be used if you will not draw any box on image above
default_box = {'x': 68, 'y': 247, 'width': 555, 'height': 678, 'label': ''}

mask_predictor = SamPredictor(sam)

for image in yolo_test_data:
    box = widget.bboxes[0] if widget.bboxes else default_box
    box = yolo_convertor(image['tensor'])[0]

    image_bgr = cv2.imread(image['image_path'])
    image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)

    mask_predictor.set_image(image_rgb)

    masks, scores, logits = mask_predictor.predict(
        box=box,
        multimask_output=True
    )
    
    mask_annotator = sv.MaskAnnotator(color=sv.Color.red())

    detections = sv.Detections(
        xyxy=sv.mask_to_xyxy(masks=masks),
        mask=masks
    )
   
    detections2 = detections[detections.area == np.max(detections.area)]

    segmented_image = mask_annotator.annotate(scene=image_bgr.copy(), detections=detections2)

    # Save image to google drive
    cv2.imwrite(os.path.join("/content/drive/MyDrive/xxx/xxx", os.path.basename(image['image_path'])), segmented_image)

解决方案

要实现保留分割区域原始色彩的透明掩码,无需依赖sv.MaskAnnotator(它的作用是给掩码填充颜色后叠加到原图),直接通过OpenCV处理图像的alpha通道即可实现需求:

方法1:生成带透明背景的目标图像

核心逻辑是给原图添加alpha通道,将非分割区域的alpha值设为0(完全透明),分割区域保留原图色彩与不透明属性:

import numpy as np
import cv2
import supervision as sv
import os
from jupyter_bbox_widget import BBoxWidget

widget = BBoxWidget()

default_box = {'x': 68, 'y': 247, 'width': 555, 'height': 678, 'label': ''}

mask_predictor = SamPredictor(sam)

for image in yolo_test_data:
    box = widget.bboxes[0] if widget.bboxes else default_box
    box = yolo_convertor(image['tensor'])[0]

    image_bgr = cv2.imread(image['image_path'])
    image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)

    mask_predictor.set_image(image_rgb)

    masks, scores, logits = mask_predictor.predict(
        box=box,
        multimask_output=True
    )
    
    detections = sv.Detections(
        xyxy=sv.mask_to_xyxy(masks=masks),
        mask=masks
    )
   
    # 筛选面积最大的分割掩码
    detections2 = detections[detections.area == np.max(detections.area)]
    target_mask = detections2.mask[0].astype(np.uint8) * 255

    # 给原图添加alpha通道(BGRA格式)
    image_rgba = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2BGRA)
    # 将非掩码区域的alpha值设为0,实现透明效果
    image_rgba[:, :, 3] = target_mask

    # 保存为PNG格式(JPG不支持透明通道)
    save_filename = os.path.basename(image['image_path']).replace('.jpg', '.png')
    save_path = os.path.join("/content/drive/MyDrive/xxx/xxx", save_filename)
    cv2.imwrite(save_path, image_rgba)

方法2:生成单独的透明掩码文件

如果仅需要单独的透明掩码(仅分割区域不透明,其余区域完全透明),可以直接处理掩码生成单通道alpha图:

# 承接上述代码,得到target_mask后执行:
mask_rgba = np.zeros((target_mask.shape[0], target_mask.shape[1], 4), dtype=np.uint8)
mask_rgba[:, :, 3] = target_mask  # 仅alpha通道保留掩码信息
cv2.imwrite("transparent_mask.png", mask_rgba)

补充说明

  • 虽然sv.MaskAnnotator的color参数支持带透明度的颜色(比如sv.Color(r=255, g=0, b=0, a=0)),但这种设置会让掩码区域完全透明,非掩码区域仍显示原图,无法实现“仅保留分割区域、其余透明”的效果,因此更推荐使用alpha通道处理方案。
  • 透明图像必须保存为PNG格式,JPEG格式不支持alpha通道,会丢失透明信息。

内容的提问来源于stack exchange,提问作者Milan van beek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 15:55:04