python-对图片中的人体换背景色
要“将图片中的人体全部抠出来,并放到一个新图片上”,在 Python 里推荐用深度学习语义分割模型(如 rembg、Detectron2、Segment Anything等),最简单的是 rembg ——零代码门槛,适合人像抠图任务。
方法一:用 rembg 自动抠人像
1、安装
pip install rembg pillow
2、代码(抠人体,合成到新背景)
from rembg import remove
from PIL import Image# 读取原图,自动抠出人体(主体)
src = Image.open('input.jpg')
# 主体透明图
human = remove(src)
# 读取或生成新背景(尺寸一致)
# 方式A:纯色背景
bg = Image.new('RGBA', human.size, (255, 255, 255, 255)) # 白底
# 方式B:任意图片背景
#bg = Image.open('background.jpg').resize(human.size)
# 合成人体到新背景
bg.paste(human, (0,0), human)
bg.save('human_cutout.png')
# 若要保存为 JPEG,则需转换(不支持透明)
if bg.mode == 'RGBA':# 将透明区域变成白色result = Image.new('RGB', bg.size, (255,255,255))result.paste(bg, mask = bg.split()[3]) # 使用Alpha通道为遮罩result.save('human_on_newbg.jpg')
说明
1、remove(input_image) 会自动识别人像并抠出来,结果是 RGBA 格式,有透明通道。
2、新背景可自定义(是图片,也可以是纯色)。
3、合成时用 paste,第三个参数指定前景的透明遮罩,保证人体形状自然贴合。
4、最终保存为 PNG 支持透明。若需要 JPEG,要先转换,否则会报错。
MAC 安装 pytorch 和 detectron2
-
安装 Anaconda 或 Miniconda(建议)
如果没安装过 Conda,可以先到 Miniconda官网(https://www.anaconda.com/docs/getting-started/miniconda/main) 下载并按提示安装。
这样之后所有包都在虚拟环境里,和系统库隔绝,最安全。 -
新建并激活虚拟环境
conda create -n d2_env python=3.10
conda activate d2_env
- 安装 PyTorch (适合 Mac CPU)
对于 Mac(M系列芯片或Intel芯片),PyTorch通常选 CPU 版本。
pip install torch torchvision torchaudio
或直接用官方推荐命令(PyTorch官网):
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
- 安装 Detectron2
方法一:CPU(最通用)
pip install detectron2 -f https://dl.fbaipublicfiles.com/detectron2/wheels/cpu/torch2.0/index.html
根据 PyTorch 版本和你的 Python 版本选择合适的链接(此处举例是 torch 2.0)。
常用轮子下载列表在:https://github.com/facebookresearch/detectron2/blob/main/INSTALL.md
方法二:源码安装
如果有特殊 PyTorch 版本或者遇到兼容问题,也可以直接源码安装:
python -m pip install 'git+https://github.com/facebookresearch/detectron2.git'
- 验证安装
import torch
import detectron2
print(torch.__version__)
print(detectron2.__version__)
方式二: Detectron2 (人体实例分割)
Detectron2 可以自动识别图片中的每个人体,并为每个人各自输出 mask。
简单流程
import cv2
from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg
from detectron2 import model_zoo# 配置模型(COCO实例分割,支持人体"person"类别)
cfg = get_cfg()
cfg.MODEL.DEVICE = "cpu" # 可换成 "cuda:0" 用GPU
cfg.merge_from_file(model_zoo.get_config_file('COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml'))
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url('COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml')
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.7 # 置信度阈值predictor = DefaultPredictor(cfg)img = cv2.imread('input.jpg')
outputs = predictor(img)
inst = outputs['instances']# 得到所有人体实例的mask
person_indices = (inst.pred_classes == 0).nonzero() # COCO类别0是person
for idx in person_indices.flatten():mask = inst.pred_masks[idx].cpu().numpy() # mask.shape = (H, W), bool类型# 这里你可以保存mask,或者直接用于剪裁cv2.imwrite(f'person_{idx}_mask.png', mask.astype('uint8')*255)
说明:
1、person_indices 可以得到所有检测到的“人体”对象的索引。
2、inst.pred_masks 每个 index 都是一个二值 mask。
2. Segment Anything (SAM):多实例分割
Segment Anything 能对整张图片自动返回所有可分割区域,并可筛选出“人体”区域。
(SAM不直接输出 COCO 类别,但可用条件过滤,或者利用 prompt/bbox筛定对象)
示例:自动分割出所有区域,人工选择人体 mask
(详细安装见:https://github.com/facebookresearch/segment-anything)
import numpy as np
import cv2
from segment_anything import SamAutomaticMaskGenerator, sam_model_registry# 加载模型(需提前下载SAM权重)
sam = sam_model_registry["vit_h"](checkpoint="path/to/sam_vit_h.pth")
mask_generator = SamAutomaticMaskGenerator(sam)
image = cv2.imread('input.jpg')
masks = mask_generator.generate(image) # 每个结果里有 'segmentation' 数组
for i, m in enumerate(masks):mask = m['segmentation'] # shape (H,W) bool类型# 此处 mask 只表示可分割对象,要筛选出人体需进一步筛查(比如用bbox大小/位置/或检测类别模型辅助判断)cv2.imwrite(f'sam_mask_{i}.png', mask.astype('uint8')*255)
注意:
SAM输出一批 mask(人体、物体、背景分割候选),需用 bbox 位置、区域形状等算法筛出人体(如与你的目标区域重叠最大等)。