如何基于PSD中的真值轮廓单独提取图像中的目标对象?
提取PSD中轮廓对应的目标对象解决方案
嗨,我来帮你搞定这个问题!你现在的代码只是把轮廓层导出成了图片,但要提取对应的目标对象,核心思路是用轮廓作为「掩码」,从原始图像层里抠出对应区域。下面一步步来:
第一步:先搞清楚你的PSD层结构
首先得确认PSD里哪层是原始图像,哪层是轮廓层,避免找错层。可以先跑这段代码打印所有层的信息:
from psd_tools import PSDImage psd = PSDImage.load('dna-0.psd') # 遍历所有层,打印索引和名称 for i, layer in enumerate(psd.layers): print(f"Layer {i}: {layer.name}")
运行后你就能看到类似Layer 0: 轮廓组、Layer 1: 原始图像这样的输出,记好原始图像层的索引或名称。
第二步:用轮廓生成掩码并提取对象
根据你的轮廓类型(填充区域/线条轮廓),分两种情况处理:
情况1:轮廓是填充好的区域(白色为对象,黑色为背景)
如果你的轮廓层已经是填充好的二值图(比如对象区域是白色,背景黑色),直接用这段代码:
from psd_tools import PSDImage from PIL import Image # 加载PSD文件 psd = PSDImage.load('dna-0.psd') # 替换成你实际的层索引/名称 contour_layer = psd.layers[0] # 你的轮廓层 original_layer = psd.layers[1] # 原始图像层 # 转成PIL图像 contour_img = contour_layer.as_PIL().convert('L') # 转灰度图 original_img = original_layer.as_PIL() # 生成二值掩码:过滤灰色噪点,白色区域设为255(完全不透明),黑色设为0(透明) mask = contour_img.point(lambda x: 255 if x > 200 else 0) # 创建透明背景的新图,把原始图像按掩码粘贴进去 extracted_obj = Image.new('RGBA', original_img.size, (0, 0, 0, 0)) extracted_obj.paste(original_img, mask=mask) # 保存提取好的对象 extracted_obj.save('dna-0_extracted_object.png')
情况2:轮廓是线条状(只有边界线条,没有填充)
如果你的轮廓只是黑色线条(白色背景),那得先把线条内部填充成白色,再生成掩码:
from psd_tools import PSDImage from PIL import Image, ImageDraw psd = PSDImage.load('dna-0.psd') contour_layer = psd.layers[0] original_layer = psd.layers[1] contour_img = contour_layer.as_PIL().convert('L') original_img = original_layer.as_PIL() # 填充轮廓内部:假设图像中心是对象内部(如果不对,换个内部点坐标就行) draw = ImageDraw.Draw(contour_img) center_x, center_y = contour_img.size[0] // 2, contour_img.size[1] // 2 # 用白色填充轮廓内部 draw.floodfill((center_x, center_y), 255) # 生成掩码 mask = contour_img.point(lambda x: 255 if x == 255 else 0) # 粘贴提取对象 extracted_obj = Image.new('RGBA', original_img.size, (0, 0, 0, 0)) extracted_obj.paste(original_img, mask=mask) extracted_obj.save('dna-0_extracted_object.png')
小提示
- 如果填充的时候出现漏填或者填到外部,说明你选的填充点不对,可以找一个确定在对象内部的坐标替换
(center_x, center_y)。 - 阈值
200可以根据你的轮廓颜色深浅调整,确保把所有轮廓区域都识别成白色。
内容的提问来源于stack exchange,提问作者Jame
相关产品推荐
相关产品推荐

