python-自定义抠图
在 Python 中,实现“抠图”功能有多种方式。常用的方法包括:
1、基于颜色抠图(容易实现,适合背景比较纯色的图像)
2、基于语义分割/深度学习模型抠图(适用于复杂背景)
3、基于传统图像分割算法如GrabCut(效果较好,操作简单)
方法一:基于颜色抠图(适合纯色背景)
from PIL import Image
import numpy as np
img = 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 cv2
import numpy as np
from 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) * 255
data[..., 3] = alpha
extract = Image.fromarray(data)
extract.save('grabcut_extract.png')
说明:
cv2.grabCut方法自带半自动抠图能力,初次使用可通过调整rect参数确定主体大致范围。
抠好后保留前景,背景都去掉或者变透明。
方法三:基于深度学习的自动抠图
pip install rembg pillow
from rembg import remove
from PIL import Imageinput_path = 'input.jpg'
output_path = 'rembg_extract.png'img = Image.open(input_path)
out = remove(img)
out.save(output_path)