如何用Python实现JPG白底转透明且保留原图色彩?
问题原因
色彩变化的核心原因是OpenCV与PIL的色彩通道顺序不一致:
- OpenCV读取彩色图像默认是BGR(蓝、绿、红)通道顺序,转成BGRA后是B、G、R、A
- PIL处理图像默认是RGB(红、绿、蓝)通道顺序,直接将OpenCV的BGRA数组传给PIL,会导致红、蓝通道颠倒,色彩失真
修改后的代码
import cv2 import numpy as np from PIL import Image # 文件路径和文件名 path = "images/" filename = "demo.jpg" input_filepath = path + filename output_filepath = path + "demo_transparent.png" # 读取彩色图像 img = cv2.imread(input_filepath) # 转换为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 定义阈值 thresh = 250 # 阈值化图像 _, binary = cv2.threshold(gray, thresh, 255, cv2.THRESH_BINARY) # 查找图像中的轮廓 contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 创建一个全白的掩码 mask = np.ones_like(gray) * 255 # 绘制找到的轮廓,填充内部区域 cv2.drawContours(mask, contours, -1, 0, thickness=cv2.FILLED) # 反转掩码 mask = cv2.bitwise_not(mask) # 将BGR图像转换为RGBA(先转RGB再加Alpha通道) rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) rgba = np.dstack((rgb, np.full_like(gray, 255))) # 应用掩码设置透明背景 rgba[mask == 255] = [255, 255, 255, 0] # 将结果保存为PNG图像 result = Image.fromarray(rgba) result.save(output_filepath) print(f"Processed image saved at: {output_filepath}")
关键改动说明
- 将OpenCV的BGR格式先转为RGB:
cv2.cvtColor(img, cv2.COLOR_BGR2RGB),匹配PIL的通道顺序 - 用
np.dstack直接给RGB图像添加全不透明的Alpha通道,替代原有的COLOR_BGR2BGRA转换 - 替换原有的双层循环,用numpy数组索引直接批量设置透明像素,效率更高,同时避免循环中的判断误差
- 直接通过掩码匹配背景区域,设置对应像素的Alpha通道为0,同时保持RGB通道为白色(不影响透明效果)
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

