宠物写真成组产出
从几张手机实拍照出发,产出同一只宠物在指定场景下的一组写真,并交付可直接打印的成品。
何时用
用户提供宠物实拍照 + 想要某个场景/风格的成组照片时。典型触发:
"给家里金毛出一组海边写真""仿英宠摄影张天航的手法""换草原场景再来一组"。
核心心法
这不是"生成好看的宠物图",这是"照着这只真实的动物做东西"。
主人看的是"像不像我家那只",不是"美不美"。
所以:身份锚点优先于画面美感;验证优先于交付;姿态与毛色的反例约束必须写死。
步骤
1. 读原片,建立模特档案
逐张 Read 原片,判读并记录:
- 品种 / 年龄(老年犬猫看口鼻、眼周泛白程度)
- 体型(壮实 vs 精瘦;估重)
- 毛色分区(背线色 / 胸腹四肢色)
- 最可辨识的单点特征(特殊的尾巴形状、项圈颜色、耳朵、疤)
- 配饰(项圈颜色 + 卡扣)—— 这是重要的身份锚点
- 原片里有哪些"污染源"(牵引绳、胸背带、嘴罩)—— 必须显式排除
写进一份档案,后面每张图的提示词都复用同一段。
2. 压缩参考图
原片通常 4~5MB,直接做图生图会报 Request body larger than maxBodyLength limit。
压到长边 640px / JPEG q78(约 80KB),记得 ImageOps.exif_transpose 修手机照片的旋转标记。
最多 3 张参考图,挑选原则:全身侧面(读体型)+ 脸部特写(读年龄与眼神)+ 尾部或配饰(读辨识点)。
压缩脚本存成 _prep_refs.py,放在该组目录下。
3. 定提示词骨架(四段式)
每次出图都照这个结构写,顺序不要变:
[第 1 段 · 身份锚点]
Keep the EXACT same dog as in the reference photos. Every one of these identity
anchors must be clearly visible:
- 品种 + 年龄 + 是否老年
- 泛白区域(口鼻/下巴/眼周)—— 老年宠物这是第一重要特征
- 毛色,用 "make this exact:" 强势句式点名
- 白色饰毛区域
- 鼻/眼描述
- 项圈颜色 + 卡扣
- 体型,并写 NOT slim, NOT athletic
[第 2 段 · 硬约束(反例必须写死)]
CRITICAL - TAIL CARRIAGE: ... NOT raised, NOT carried over the back,
NOT lifted like a flag, NOT curled upward.
CRITICAL - NO EQUIPMENT: NO leash, NO rope, NO strap, NO cord, NO metal clip,
NO snap hook, NO D-ring, NO harness anywhere in the frame.
[第 3 段 · SCENE]
具体场景、动作、决定性瞬间、环境元素。
[第 4 段 · 摄影手法 + 真实感要求]
摄影师风格 + 机位 + 光线 + 镜头焦段 + 真实感反例清单。
反例清单(真实感)——逐条否定,否则模型一定往"假"的方向跑:
> NOT a neon-green postcard, NOT HDR, no teal-orange grading, no fantasy glow,
> no glossy commercial advertisement, do NOT oversaturate.
> Realistic: muted natural colours, dull mixed grass, film-like colour response,
> subtle fine grain, mild contrast, atmospheric haze, ordinary imperfect documentary framing.
4. 出图 —— 必须串行
一次只发一个出图调用。 同一条消息里并行发多个(哪怕各自传了不同 output_dir),
会出现参数互相覆盖、全部写进同一目录、同秒文件互相覆盖丢图。
每张给独立的 output_dir(输出名只精确到秒)。
- 横版用
1536x1024,竖版肖像用1024x1536 input_fidelity: high,quality: high- 组图要有叙事弧(5 张建议:抵达 → 试探 → 关键场景 → 释放 → 安静的收束),
其中一张是"题眼",即最能代表这个场景与这只宠物的那一张。
5. 逐张验收(不许跑完就报成功)
对每张:
- 全图看一遍:尾巴姿态 / 体型胖瘦 / 口鼻白度 / 毛色深浅 / 有没有绳或挂件 / 有没有多腿
- 裁出项圈和尾部区域,放大 2~6 倍再看一遍
—— 金属挂件在整图里常常只有几个像素,肉眼一定会漏 - 不合格就重出或二次图生图修
二次图生图去杂物的写法:明确列出要移除的物体,强调"项圈保留、其余完全不变",
并把原图的场景要素逐条复述一遍防止跑偏:
> Retouch this photograph: completely remove the [物体], the [部件] ...
> The collar must remain exactly as it is, sitting naturally with NOTHING attached to it.
> Keep EVERYTHING ELSE byte-for-byte identical: the same ... , the same ... , the same
> composition, framing and aspect ratio. Only [物体] is removed, filling that area
> naturally with [毛发/背景]。
6. 裁水印
出图服务会在右下角叠加固定像素尺寸的 "AI生成 WORKBUDDY" 水印,提示词管不了。
统一裁掉底部 122px(1536x1024 → 1536x902;1024x1536 → 1024x1414),构图基本无损。
带水印原图归档到 _过程文件\出图原图_带水印\。
7. 高清化(两步,服务只做第一步)
第一步 · 画质增强(buddy-image-processing skill 的 enhance):
先取调用凭据,然后:
python ".../skills/buddy-image-processing/scripts/buddy-image-processing.py" \
image-edit --operation enhance \
--image-file "<绝对路径>" \
--prompt "高清化:提升画质,恢复毛发与<场景细节>细节,保持自然摄影质感" \
--token "<clientTempToken>"
- 输出分辨率不变,只提边缘锐度。别指望它给大图。
- 结果落在工作区根目录(
processed_image_<task_id>_1.jpg),需自己搬。 - 输出名带 task_id,可以串行连着跑(与出图不同,这里并行/串行都不会撞名)。
- token 有效期约 15 分钟,5 张约 1 分钟跑完。
核对:算 Laplacian 方差对比处理前后(正常提升 70%~150%),
并且一定要肉眼验——数字涨了但锐化过头会毁掉毛发质感。
第二步 · 2 倍放大(自己做,服务没这参数):
Lanczos 重采样 + UnsharpMask(radius=1.6, percent=52, threshold=3)
——锐化刻意压克制,过度锐化先毁毛发。放大后在 100% 原生像素下核对一遍。
8. 交付
- 成品 JPG 在组目录根,
2倍放大\放打印版 00_选集预览.jpg:一屏看全(建议 3+2 版式:三个横版一行,一个横版 + 一个竖版一行,
浅暖色底、居中标题、图下小字标注)_对比_高清前后.jpg:同一裁切区左右并排拍摄说明.md:模特档案 / 摄影手法 / 分镜表 / 本轮踩的坑 / 高清化数据 / 文件说明 /
复现方法 / 还能怎么加- 中间稿全部归入
_过程文件\,根目录只留成品、放大版、预览、对比图、说明、脚本 - 用
present_files交付
附带脚本
scripts/ 里是本流程可直接复用的工具,都只依赖 Pillow(pip install pillow),全部实测跑通过。
路径按技能安装位置解析,例如 ~/.workbuddy/skills/pet-photo-set/scripts/。
| 脚本 | 用途 | 示例 |
|---|---|---|
prep_refs.py |
压参考图到长边 640px / q78,自动修 EXIF 旋转 | python prep_refs.py ./原片 -o ./refs |
zoom_check.py |
验收用:裁指定区域放大 2~6 倍核对项圈挂件/尾巴/口鼻;--grid 先出坐标网格 |
python zoom_check.py 01.jpg --box 700,470,1010,690 -z 3 |
finalize_watermark.py |
裁掉底部 122px 水印、归档带水印原图、批量重命名 | python finalize_watermark.py -d ./出图 -o ./_高清化前 --map map.txt |
upscale_2x.py |
Lanczos + USM(1.6/52/3) 放大 | python upscale_2x.py -d ./草原写真 |
make_preview.py |
3+2 选集预览图;加 --before 出高清前后对比图 |
python make_preview.py -d ./草原写真 --title "呼伦贝尔 · 草原写真" |
zoom_check.py 是这套流程里最值钱的一个——金属挂件在整图上常常只有几个像素,肉眼扫全图一定会漏。
参考:摄影师风格要点(英宠摄影 张天航)
不控制宠物只抓决定性瞬间 / 贴地低机位与眼齐平 / 只用自然光绝不用闪光 /
不以标准体态为美,拍性格与眼神 / 24-70 f2.8、70-200 f2.8、85 f1.8 /
经典画面是"狗被浪追、最后坐在浪线外看海"。
换成别的场景时,"海"替换成对应场景的关键元素(草原→草浪与河湾;麦田→麦浪;雪地→雪坡),
手法六条不变。
踩坑速查
| 症状 | 原因 | 解法 |
|---|---|---|
Request body larger than maxBodyLength |
参考图是 4~5MB 原片 | 先压到长边 640px / q78 |
| 出图成功但文件不见了 | 并行调用导致 output_dir 互相覆盖 + 同秒覆盖 | 出图串行,每张独立 output_dir |
| 项圈上多了金属环 / 弹簧扣 | 原片里的牵引绳被连带学过去 | 二次图生图定向移除;提示词里逐个点名 NO metal clip / D-ring / snap hook |
| 尾巴被画成上扬"旗尾" | 模型按年轻犬标准相画 | 写死 hang DOWN and LOW … NOT lifted like a flag |
| 毛色偏浅偏奶油 | 只写 coat colour 力度不够 | 用 make this exact: DEEP WARM … NOT pale cream, NOT near-white |
| 画面有 AI 塑料感 | 缺真实感反例 | 逐条否定 HDR / 青橙调 / 荧光绿 / 梦幻光晕 / 过饱和,要胶片颗粒与不完美构图 |
| 右下角有水印 | 服务端叠加,提示词管不了 | 统一裁掉底部 122px |
| 高清化后没变大 | enhance 不改分辨率 |
放大自己做:Lanczos + USM |