同一张图跑两次结果差很多——img2threejs 的输出稳定吗?

文章导读
先分清两件事:同一张图两次输出差很多,可能是流程里某个输入环节没固定住(缩放、裁剪、背景、透明通道、参数默认值),也可能是生成环节本身带非确定性。判断办法不复杂——用同一份输入连续跑三次,把可量化的输出项列成表逐项对比;确认差异真实存在后,再固定其余条件、只改一个输入变量,看差异是跟着图片走还是跟着流程走。能固定的部分写成操作约定,固定不了的部分按可用性标准决定接受波动还是换流程。
📋 目录
  1. 壹 把同一张图连跑三次,逐项对比输出
  2. 贰 固定其余条件,只改一个输入变量
  3. 叁 区分随机性与输入敏感性的表现差异
  4. 肆 把可固定的部分写成操作约定
  5. 伍 给不可复现的部分定一个可用性判断
A A

先分清两件事:同一张图两次输出差很多,可能是流程里某个输入环节没固定住(缩放、裁剪、背景、透明通道、参数默认值),也可能是生成环节本身带非确定性。判断办法不复杂——用同一份输入连续跑三次,把可量化的输出项列成表逐项对比;确认差异真实存在后,再固定其余条件、只改一个输入变量,看差异是跟着图片走还是跟着流程走。能固定的部分写成操作约定,固定不了的部分按可用性标准决定接受波动还是换流程。

同一张图重复运行结果不一致,通常不是单一原因。建议先做三次重复实验,记录网格数量、比例、朝向、材质命名、贴图数量五项;若换分辨率或裁剪方式后差异方向随之改变,属于输入敏感性,靠预处理约定解决;若输入完全一致仍有差异,属于生成环节的非确定性,只能通过锁定参数、保留基线版本、人工后处理来收敛。边界是:不要用一次对比就下“稳定”或“不稳定”的判断,也不要指望某个参数能消除全部波动。

把同一张图连跑三次,逐项对比输出

重复实验的目的不是证明工具有问题,而是先把“感觉差很多”落到具体字段上。建议用同一份原始图片、同一套参数,连续跑三次,输出到三个独立目录,避免后一次覆盖前一次。下面的命令只是通用骨架,把 img2threejs 换成实际调用的命令或脚本入口即可。

mkdir -p runs
for i in 1 2 3; do
  mkdir -p "runs/run-$i"
  img2threejs `--input` ./cases/case-01/input/preprocessed.png \
              `--out` "runs/run-$i"
done

如果输出是 glTF/GLB,网格、材质、贴图数量可以直接从文件结构里读出来,比肉眼数更可靠(GLB 需要先转成 JSON 或解包):

for d in runs/run-*; do
  f=$(find "$d" -name '*.gltf' | head -n 1)
  printf '%s\t' "$d"
  jq -r '[ (.meshes // [] | length),
           (.materials // [] | length),
           (.textures // [] | length) ] | @tsv' "$f"
done

比例和朝向没有统一字段可读,建议在三维预览里截图,用同一视角、同一相机参数各存一张,人工比对包围盒长宽高与主体朝向。材质命名也建议直接抄下来而不是“看着差不多”。对比项固定为五项,记成一张表:

对比项run-1run-2run-3是否一致
网格数量
整体比例(包围盒长宽高)
主体朝向
材质命名
贴图数量

三次全一致,说明在当前输入下输出是稳定的;三次里有两项以上不一致,才值得继续往下查。只跑两次很容易把“一次正常、一次异常”误当成随机,三次能看出是离散跳变还是连续抖动。

固定其余条件,只改一个输入变量

差异有可能来自图片本身,比如同一物体换了拍摄角度、背景里多了杂物、图片被不同软件重新压缩过。判断时把变量清单列清楚,然后一次只动一项:

同一张图跑两次结果差很多——img2threejs 的输出稳定吗?
  • 图片本体:原图、截图、二次导出图,分别作为输入各跑三次
  • 分辨率:长边 512、1024、2048 各跑三次,保持裁剪方式不变
  • 裁剪方式:原始整图、居中裁正方形、按主体外接框裁,各跑三次,保持分辨率不变

单变量对比的做法是“同变量三跑 + 跨变量一比”。例如先固定 1024 居中裁,只把输入图从 A 换成 A 的二次导出图,看五项对比表是否变化;若变化明显,问题在图片预处理而不是生成环节。再固定同一张图,只把长边从 1024 改到 2048,看网格数量和贴图数量是否随之跳档。跨变量比较时,每次只保留一个变量不同,其余参数写进命令里显式指定,不要依赖默认值——默认值在不同调用方式下可能不一致。

区分随机性与输入敏感性的表现差异

把输入问题当成随机问题,会导致反复重跑而不去修预处理;反过来把随机问题当成输入问题,会不断换图却始终没改善。两类差异有比较明显的表现特征,可以先按下面几条粗判:

  • 输入敏感性:输入一改,输出跟着系统性变化,比如分辨率翻倍后网格数量稳定上升;同一输入重复跑,结果基本一致或差异集中在同一处。
  • 随机性:输入完全一致、参数完全一致,多次运行仍在同一量级上跳动,网格数量、材质命名顺序、贴图数量都可能变;换输入后波动幅度没有明显收敛。

记录方式上,建议每次运行都留一份同名字段的记录文件,而不是事后凭记忆补:

run_id,input_file,resolution,crop,mode,mesh_count,bbox,orientation,materials,textures,notes
run-1,preprocessed.png,1024,center,default,,,,,,
run-2,preprocessed.png,1024,center,default,,,,,,
run-3,preprocessed.png,1024,center,default,,,,,,

记录里的 mode 用来区分是否启用了带随机性的采样或生成模式;如果工具提供固定种子或固定采样参数的入口,把它打开再跑一轮,前后两组记录对比,就能看出随机性占到多大比重。没有固定种子入口时,只能靠重复次数和波动范围来描述,不要凭一次结果下判断。

把可固定的部分写成操作约定

可复现的前提是“下次还能一模一样地做一遍”。约定不需要复杂,写清楚三件事就够用:图片预处理方式、输出目录命名、每次记录的字段。目录可以按下面结构组织,让输入和结果一一对应:

同一张图跑两次结果差很多——img2threejs 的输出稳定吗?
cases/case-01/
  input/original.png
  input/preprocessed.png     # 统一长边、统一裁剪后的输入
  input/preprocess.md        # 预处理步骤说明
  runs/<ts>-a/
  runs/<ts>-b/
  record.csv

预处理约定建议固定为:长边统一到同一像素值、统一裁成正方形或统一保留原比例但记录裁剪框、统一转成无透明通道的 RGB、统一背景处理方式(保留原背景或统一去背)。输出目录命名带时间戳和序号,避免覆盖,也方便事后定位是哪一次跑出来的。每次记录字段至少包含:运行标识、输入文件名与哈希、分辨率、裁剪方式、调用参数、五项对比项结果、人工备注。输入文件哈希可以顺手算一下,用来确认“同一张图”确实是同一张:

sha256sum cases/case-01/input/preprocessed.png

约定写下来之后,后续所有对比都以这份约定为基准。改约定本身也要记一笔,否则新旧结果混在一起,又会回到“不知道哪一版能信”的状态。

给不可复现的部分定一个可用性判断

不是所有波动都需要消除。判断标准可以先落在用途上:如果输出只用于看结构关系、做草模参考,网格数量和材质命名的小幅波动一般不影响使用;如果输出要进后续建模流程、要和其他资产对齐坐标和比例,比例与朝向不一致就必须处理,否则下游返工成本更高。

处置方向大致三种,选一种执行,不要混着来:

  1. 接受波动并加后处理:适用于草模、示意图场景。固定一套预处理约定,每次输出后统一做一次尺度归一化和朝向校正,把波动挡在下游之前。
  2. 锁定基线版本:从多次运行里挑一版结构最合理的作为基线,后续只做增量修改而不是重新生成。代价是失去“重新跑一次可能更好”的机会,但结果可比、可回溯。
  3. 换流程:当同一输入在多次运行里连比例和朝向都无法收敛,说明当前调用方式不适合这个用途。可以先试固定种子、降低输入分辨率波动、简化输入背景,仍不收敛再考虑改用更可控的建模路径。

三种方向的选择依据建议写进项目记录:用途是什么、可接受的波动范围是什么、由谁判定。判断标准写清楚之后,“同一张图跑两次结果差很多”就从情绪问题变成可执行的取舍。