如何用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
相关产品推荐
相关产品推荐

