部分的图像分割模型,容易输出边缘带毛刺的抠图结果,这里使用高斯模糊进行后处理,高斯模糊的参数建议只调节高斯卷积核的大小,调的越大越模糊。
输入为mask 和原图,两个shape需要一致,mask为png,抠图中心为透明,其他背景区域为黑色如下图:
import numpy as np
import cv2
from loguru import logger
def GaussianBlur(img_path, mask_svg_path, gau_hei, save_path, input_file):
if not os.path.exists(save_path):
os.makedirs(save_path)
image = cv2.imread(img_path, cv2.IMREAD_COLOR) # 原图 忽略alpha通道
mask_svg = cv2.imread(mask_svg_path, cv2.IMREAD_UNCHANGED) # 加载全部通道包括alpha
gau_hei = str(gau_hei)
if image.shape[:2] != mask_svg.shape[:2]:
logger.info(f"image.shape:{image.shape}, mask_svg.shape : {mask_svg.shape}") # :(3024, 4032, 3)
logger.info(f"输入图片:{img_path}、输入mask:{mask_svg_path}")
logger.info(f"前两维维度不同!")
return
mask = np.zeros((mask_svg.shape[0],mask_svg.shape[1], 4), dtype=np.uint8) # 创建一个新图为mask_svg添加新通道
alpha = mask_svg[:, :, 3] # 中间透明,周围实心
mask[np.where(alpha == 0)] = [255, 255, 255, 255] # 将中间透明的部分变成白色
cv2.imwrite('output/mask.png', mask)
# 这里做透明度区分
gray = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY) # 将mask 转为灰度图像
# # 一、创建一个新图为mask_svg添加新通道
mask[:, :, 3] = np.where(gray > 127, 255, 0) # 将白色部分设置为不透明,其他部分设置为透明
cv2.imwrite('output/0614/graymask.png', mask)
# 二、 为图片创建alpha通道
image_with_alpha = np.zeros((image.shape[0], image.shape[1], 4), dtype=np.uint8)
image_with_alpha[:, :, :3] = image
image_with_alpha[:, :, 3] = 255 # 设置透明度通道为完全不透明
# 获取图像的宽度和高度
gau_hei = int(gau_hei)
gau_wid = gau_hei
logger.warning(f"高斯核函数高:{gau_hei},宽:{gau_wid}")
blur_mask = mask
if gau_hei != 0:
sp = blur_mask.shape # 读取图片长宽
blur_mask = cv2.GaussianBlur(blur_mask, (gau_hei, gau_wid), 0) # 35太猛,改为其他奇数
cv2.imwrite('output/blur_mask.png', mask)
else:
blur_mask = mask
# 不出现黑边,但是羽化周围模糊的部分会取原图
image_with_alpha[:, :, 3] = blur_mask[:, :, 3]
out = image_with_alpha
cv2.imwrite(img_path.replace('.jpg',f'羽化_{str(gau_hei)}.png').replace(input_file,save_path), out, [cv2.IMWRITE_PNG_COMPRESSION, 9])
if __name__ == '__main__':
input_file = 'test'
img_path= f"{input_file}/origin{i}.jpg"
mask_svg_path = f"{input_file}/mask{i}-1.png"
save_path = f'output/'
# 高斯模糊
for gau_hei in [
3,5,7,9
]:
GaussianBlur(img_path, mask_svg_path,gau_hei,save_path, input_file)