You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python复现Photoshop Refine Edge实现二值掩码转非二值图像

Python复现PS Refine Edge(4px半径)软边缘效果方案

PS中Select and Mask模块下Refine Edge半径设为4px处理二值图的核心逻辑,是仅在原始黑白硬边缘两侧4px范围内生成平滑灰度过渡带,远离边缘的纯黑、纯白区域完全保留原始值,最终得到边缘抗锯齿的非二值软边图像,可通过以下两种方式实现:

方案1:OpenCV距离变换实现(还原度最高)

该方案和PS Refine Edge的底层计算逻辑一致,生成效果匹配度最高:

  • 首先对输入二值图做L2距离变换,计算每个像素到最近黑/白交界线的距离
  • 以4px为阈值截断距离值,将距离映射为0-255的灰度过渡值
  • 距离边缘超过4px的区域直接保留原始纯黑/纯白值,避免全图模糊
import cv2
import numpy as np

def ps_refine_edge(binary_img, edge_radius=4):
    # 统一转单通道灰度格式
    if len(binary_img.shape) == 3:
        gray = cv2.cvtColor(binary_img, cv2.COLOR_BGR2GRAY)
    else:
        gray = binary_img.copy()
    # 确保输入为标准二值图
    _, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

    # 计算像素到最近黑色像素的距离
    dist_map = cv2.distanceTransform(binary, cv2.DIST_L2, 5)
    dist_map = np.clip(dist_map, 0, edge_radius)
    # 线性映射生成灰度过渡带
    soft_mask = (dist_map / edge_radius * 255).astype(np.uint8)
    # 非边缘区域保留原始二值
    soft_mask[dist_map >= edge_radius] = 255
    soft_mask[dist_map <= 0] = 0

    return soft_mask

# 调用示例
if __name__ == "__main__":
    input_img = cv2.imread("input_binary.png", cv2.IMREAD_GRAYSCALE)
    output = ps_refine_edge(input_img, edge_radius=4)
    cv2.imwrite("soft_edge_output.png", output)

如果需要匹配PS默认的高斯柔边曲线,可将线性映射替换为高斯衰减逻辑:

soft_mask = (255 * (1 - np.exp(-(dist_map**2)/(2*(edge_radius/2)**2)))).astype(np.uint8)

方案2:Pillow实现(轻量无OpenCV依赖)

如果不想安装OpenCV,可通过Pillow的滤波组合实现近似效果,逻辑是先提取边缘区域,仅对边缘部分做对应半径的高斯模糊,非边缘区域保留原始硬边:

from PIL import Image, ImageFilter, ImageChops

def ps_refine_edge_pil(input_path, edge_radius=4):
    raw_img = Image.open(input_path).convert("L")
    # 提取边缘作用区域
    max_blur = raw_img.filter(ImageFilter.MaxFilter(size=edge_radius*2+1))
    min_blur = raw_img.filter(ImageFilter.MinFilter(size=edge_radius*2+1))
    edge_mask = ImageChops.difference(max_blur, min_blur)
    # 全图高斯模糊
    gauss_blur = raw_img.filter(ImageFilter.GaussianBlur(radius=edge_radius))
    # 边缘区域用模糊结果,其余区域保留原始值
    result = Image.composite(gauss_blur, raw_img, edge_mask)
    return result

# 调用示例
output_img = ps_refine_edge_pil("input_binary.png", edge_radius=4)
output_img.save("pil_soft_output.png")

调参提示:如果输出效果和PS结果有细微差异,可在0.5px范围内微调半径参数,两种方案的输出和PS原生效果的视觉差异基本无法分辨。

内容的提问来源于stack exchange,提问作者Ahmad Uzzam Masood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:37:00