先定好输入视角再点生成——Hi3D 1.0 对输入图的几个硬要求

文章导读
同一个物体换一张图,生成结果的差异往往不在模型随机性,而在输入图本身:主视角没定、主体在画面里占比太小、背景和投影被一起喂进去。Hi3D 1.0 这类图生模型对输入视角和轮廓边界的依赖很直接,点生成之前先把视角、留白、背景三件事固定下来,比反复重试更省时间。下面按“视角选择—裁剪留白—处理背景—控制分辨率与压缩—建立对照输入”的顺序给判断依据和可执行脚本,凡涉及效果的部分都以你自己的对照输出为准。
📋 目录
  1. Ⅰ 确定主视角:正面微侧还是接近正交
  2. Ⅱ 裁掉多余留白,让主体占满画面
  3. Ⅲ 处理背景与投影
  4. Ⅳ 控制输入分辨率与压缩痕迹
  5. Ⅴ 建立一组固定对照输入
A A

同一个物体换一张图,生成结果的差异往往不在模型随机性,而在输入图本身:主视角没定、主体在画面里占比太小、背景和投影被一起喂进去。Hi3D 1.0 这类图生模型对输入视角和轮廓边界的依赖很直接,点生成之前先把视角、留白、背景三件事固定下来,比反复重试更省时间。下面按“视角选择—裁剪留白—处理背景—控制分辨率与压缩—建立对照输入”的顺序给判断依据和可执行脚本,凡涉及效果的部分都以你自己的对照输出为准。

判断顺序建议固定为:先选主视角,再裁掉留白,最后处理背景和压缩痕迹。照片清晰但角度随意,模型对不可见部分的补全仍容易走形;背景纹理复杂时,纹理可能被当成物体结构。下面的脚本和清单用来把输入条件固定住,是否改善要以同一物体的对照输出比较,不能预先承诺精度。

确定主视角:正面微侧还是接近正交

主视角决定模型能看到多少结构信息,也决定它要“猜”多少。建议先明确物体最重要的结构面是哪一个,再把相机放在能看清这个面的位置,不要在同一批输入里混用多种角度。

两种常见选择:

  • 正面微侧:相机基本在物体正前方,水平偏转一点,能同时看到正面和一小部分侧面。好处是主体比例直观,坏处是侧面信息不足时,模型容易把侧后方补成对称结构,或把背面臆造成正面结构的翻版。
  • 接近正交:正视图、顶视图这类投影很小的角度。好处是轮廓干净、比例好判断,坏处是厚度方向信息缺失,模型可能给出过度平滑的深度,或者在边缘处把结构拉平。

取舍上,如果物体前后关系明确(例如有把手、有开口),优先选正面微侧作为主视角,再补一张侧后方图作为参考;如果物体是规则几何体,正交视图更容易得到稳定的轮廓。一次生成只提交一个主视角,多视角混在一张图里通常会让补全更混乱。

裁掉多余留白,让主体占满画面

留白多意味着输入里大量像素与物体无关,模型对主体边界的判断会被稀释。建议把主体外接框裁到接近画面边缘,四周保留很小的等比边距即可,边距比例保持固定,便于后续对比。

下面的脚本用 Pillow 按包围盒裁剪:有 alpha 通道时用 alpha 的包围盒,没有时用四角背景色做差得到掩膜。

先定好输入视角再点生成——Hi3D 1.0 对输入图的几个硬要求
from PIL import Image, ImageChops

def crop_subject(src, dst, bg=(255, 255, 255), tol=12, pad_ratio=0.03):
    im = Image.open(src)
    if im.mode == 'RGBA':
        box = im.getchannel('A').point(lambda v: 255 if v > 8 else 0).getbbox()
    else:
        rgb = im.convert('RGB')
        base = Image.new('RGB', rgb.size, bg)
        mask = ImageChops.difference(rgb, base).convert('L')
        mask = mask.point(lambda v: 255 if v > tol else 0)
        box = mask.getbbox()
    if box is None:
        return None
    x0, y0, x1, y1 = box
    pad = int(max(x1 - x0, y1 - y0) * pad_ratio)
    box = (max(0, x0 - pad), max(0, y0 - pad),
           min(im.width, x1 + pad), min(im.height, y1 + pad))
    im.crop(box).save(dst)
    return box

验证方式:打印裁剪前后的尺寸,确认主体外接框四周留白接近设定比例;对同一物体分别用裁剪前和裁剪后的图生成一次,看轮廓是否更完整、部件是否被截断。如果裁剪后部件被切掉,说明阈值或边距太激进,先把 tol 调小、pad_ratio 调大再试。

处理背景与投影

纯色背景的图通常比复杂背景稳定,因为模型不需要区分桌面纹理和物体表面。木纹、布料、带字的桌面更容易让背景纹理被当成结构,出现在生成的表面上。投影也要一起处理:硬阴影常被当成物体底部的一部分,生成后底部可能变厚或出现多余几何。

拍摄阶段能解决的部分尽量在拍摄阶段解决:纯色背景布、主体离背景远一点、用柔光弱化阴影,比事后抠图更可靠。如果只能后期处理,可以用下面的阈值去背景骨架,适用于主体与背景色差明显、光照较均匀的图:

from PIL import Image
import numpy as np

def remove_bg(src, dst, tol=18):
    im = Image.open(src).convert('RGB')
    arr = np.asarray(im).astype(np.int16)
    corner = arr[0, 0].astype(np.int16)
    dist = np.abs(arr - corner).sum(axis=2)
    mask = (dist > tol * 3).astype('uint8') * 255
    out = im.convert('RGBA')
    out.putalpha(Image.fromarray(mask))
    out.save(dst)

验证方式:打开输出的 alpha 通道,放大看边缘是否残留背景块或出现锯齿;检查 alpha 直方图,如果大量像素落在中间灰度,说明边缘过渡不干净。复杂背景或半透明物体不建议只靠阈值,改用人工抠图或直接重拍更省事。

先定好输入视角再点生成——Hi3D 1.0 对输入图的几个硬要求

控制输入分辨率与压缩痕迹

重采样和 JPEG 压缩都会在轮廓边缘留下痕迹,模型可能把这些痕迹当成几何细节。处理顺序建议是:先在原始分辨率上完成裁剪和去背景,再一次性降采样到目标长边,最后保存为 PNG 或质量固定的单次 JPEG。不要先压小再放大,也不要在同一张图上反复保存 JPEG。

from PIL import Image

def normalize(src, dst, long_edge=1024, quality=95):
    im = Image.open(src)
    if im.mode not in ('RGB', 'RGBA'):
        im = im.convert('RGB')
    scale = long_edge / max(im.size)
    if scale < 1:
        size = (round(im.width * scale), round(im.height * scale))
        im = im.resize(size, Image.LANCZOS)
    if dst.lower().endswith(('.jpg', '.jpeg')):
        if im.mode == 'RGBA':
            im = im.convert('RGB')
        im.save(dst, quality=quality, subsampling=0)
    else:
        im.save(dst)

检查方法:把输入图放大到 100% 以上看物体轮廓,边缘是否发毛、是否出现块状伪影或彩色镶边;如果有,说明压缩痕迹已经进入输入,换 PNG 中间文件或重新导出通常比继续调生成参数更有效。

建立一组固定对照输入

没有固定基准时,每次调整都像重新开始。建议为一个物体保留 3 到 5 张图作为基准:一张正面微侧主图、一张接近正交视图、一张侧后方补充图、一张纯背景标准图;有遮挡或特殊部件的再加一张。基准图一旦定下,不要因为单次结果不好就换掉,先改参数再判断。

每次生成至少记录这些字段,用一张表或一份 CSV 维护:

  • 输入文件名、原始尺寸、处理后尺寸
  • 视角类型(正面微侧 / 接近正交 / 侧后方)
  • 背景类型(纯色 / 复杂 / 已抠图)与是否保留投影
  • 裁剪参数、去背景阈值、保存长边与质量参数
  • 生成时使用的可调项与输出文件名
  • 观察到的问题:补全错误出现在哪个部位、轮廓是否发毛、接缝是否明显

每次只改一个变量,例如只改裁剪边距或只改背景处理,再对照同一组基准图的输出。这样出问题时能定位到输入条件,而不是笼统地归因于“模型效果不稳定”。