> 技术文档 > python-自定义抠图

python-自定义抠图

在 Python 中,实现“抠图”功能有多种方式。常用的方法包括:
1、基于颜色抠图(容易实现,适合背景比较纯色的图像)
2、基于语义分割/深度学习模型抠图(适用于复杂背景)
3、基于传统图像分割算法如GrabCut(效果较好,操作简单)

方法一:基于颜色抠图(适合纯色背景)

from PIL import Imageimport numpy as npimg = Image.open(\'input.jpg\').convert(\'RGBA\')arr = np.array(img)# 假设背景为白色(255,255,255)r, g, b, a = arr[..., 0], arr[..., 1], arr[..., 2], arr[..., 3]mask = (r > 240) & (g > 240) & (b > 240) # 白色阈值可调整arr[mask, 3] = 0 # 白色背景设为透明result = Image.fromarray(arr)result.save(\'extract.png\')

说明:
mask 用于选出接近白色的像素,把alpha通道设为0,即该处变透明。
适用于背景单一、与主体区分明显的图片。

方法二:使用GrabCut自动前景分割(适用于普通照片)
需要用到 OpenCV:

pip install opencv-python pillow numpy
import cv2import numpy as npfrom PIL import Imageinput_path = \'input.jpg\'img = cv2.imread(input_path)mask = np.zeros(img.shape[:2], np.uint8)# 矩形框(左上x,左上y,宽,高)——可适当根据图片调整rect = (50, 50, img.shape[1]-100, img.shape[0]-100)bgdModel = np.zeros((1, 65), np.float64)fgdModel = np.zeros((1, 65), np.float64)# GrabCut分割cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)mask2 = np.where((mask==2)|(mask==0), 0, 1).astype(\'uint8\')img_cut = img * mask2[:, :, np.newaxis]# 转成PIL图片,添加透明通道img_pil = Image.fromarray(cv2.cvtColor(img_cut, cv2.COLOR_BGR2RGBA))data = np.array(img_pil)alpha = np.any(data[..., :3] != [0,0,0], axis=-1) * 255data[..., 3] = alphaextract = Image.fromarray(data)extract.save(\'grabcut_extract.png\')

说明:
cv2.grabCut方法自带半自动抠图能力,初次使用可通过调整rect参数确定主体大致范围。
抠好后保留前景,背景都去掉或者变透明。

方法三:基于深度学习的自动抠图

pip install rembg pillow
from rembg import removefrom PIL import Imageinput_path = \'input.jpg\'output_path = \'rembg_extract.png\'img = Image.open(input_path)out = remove(img)out.save(output_path)