抠图的后处理 | 羽化

部分的图像分割模型,容易输出边缘带毛刺的抠图结果,这里使用高斯模糊进行后处理,高斯模糊的参数建议只调节高斯卷积核的大小,调的越大越模糊。

输入为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)

猜你喜欢

转载自blog.csdn.net/qq_41900846/article/details/131274723