二次元人物形象编码规范

二次元人物形象编码规范(初稿 v0.1)

本规范基于此前讨论整理,用于将二次元人物形象编码为可解析、可比较、可扩展的字符串。
未定义项以 TODO 标注。

1. 范围

本规范定义:

  1. 一种“区域均值—GIF 调色板索引码”颜色摘要操作;
  2. 一张固定 256 色调色板 PAL-16x16-v1;
  3. 一种人物形象编号格式:<作品>-<角色>-<发色><眼色><呆毛><耳><角>;
  4. 已知字段的取值与解析规则。

2. 术语

术语 含义
部位 (S) 由掩膜定义的图像区域,如头发、眼睛
轮廓线 (\partial S) 部位边界或独立线稿像素
内部区域 (S') 去除轮廓线后参与统计的像素集合
平均色 (\mu) 内部区域在线性 RGB 下取平均后转回 sRGB 的颜色
调色板索引 0~255 的整数,写成两位大写十六进制
特征串 编号中最后一个 - 之后的 7 位固定长度字符串
形象 同一角色下,由特征串唯一确定的一种外观表现

3. 颜色摘要操作

3.1 输入

  • 图像 (I),sRGB;
  • 部位掩膜 (S);
  • 轮廓线掩膜 (L)(可选);
  • 轮廓宽度 (w),默认 (w=2) 像素。

3.2 去除轮廓线

若提供独立线稿掩膜 (L):

[ S' = S \setminus \mathrm{dilate}(L, w) ]

否则使用形态学腐蚀:

[ S' = \mathrm{erode}(S, w) ]

若 (S') 为空,则回退到 (S) 的中心区域或整体区域。

3.3 在线性 RGB 下取平均

将 sRGB 像素转为线性 RGB:

[ C_{\text{lin}} = \begin{cases} C/12.92, & C \le 0.04045 \ ((C+0.055)/1.055)^{2.4}, & C > 0.04045 \end{cases} ]

求平均:

[ \bar C_{\text{lin}} = \frac{1}{|S'|}\sum_{p\in S'} C_{\text{lin}}(p) ]

再转回 sRGB,得到平均色 (\mu)。

3.4 映射到固定调色板

在 PAL-16x16-v1 中寻找最近邻索引:

[ i = \arg\min_{0\le j\le 255} d(\mu, P_j) ]

默认距离为加权 RGB 距离:

[ d^2 = 2\Delta R^2 + 4\Delta G^2 + 3\Delta B^2 ]

可选用 CIELAB (\Delta E_{00}) 提升精度。

3.5 输出

输出两位大写十六进制:

[ \text{code} = \mathrm{hex2}(i) ]

例如 00、5A、FF。


4. 固定调色板 PAL-16x16-v1

4.1 索引结构

索引 (i) 写成两位十六进制 (HL):

  • 高四位 (H):色相/类别,0~F;
  • 低四位 (L):明度/深浅,0~F。

4.2 色相行定义

(H) 含义
0 无彩色灰阶行
1 红
2 橙
3 黄
4 绿
5 紫
6 粉/洋红
7 青
8 蓝
9 棕
A 橄榄
B 青绿
C 天蓝
D 靛
E 洋红
F 米色

4.3 明度规则

  • (H=0):0 最亮,F 最暗;
  • (H\ne 0):0 最亮,F 最暗;
  • 中间值线性过渡。

4.4 强制锚点

00 -> #FFFFFF 纯白
5A -> #4B0082 深紫

因此:

  • 00 表示纯白;
  • 5A 表示深紫。

4.5 生成伪代码

def build_palette():
    P = [(0, 0, 0)] * 256

    hue = {
        1: 0, 2: 30, 3: 60, 4: 120, 5: 280,
        6: 240, 7: 180, 8: 330, 9: 20, 10: 80,
        11: 160, 12: 200, 13: 260, 14: 300, 15: 40
    }
    sat = {9: 0.5, 15: 0.4}

    for H in range(16):
        for L in range(16):
            i = H * 16 + L
            if H == 0:
                v = 255 - L * 17
                P[i] = (v, v, v)
            else:
                h = hue[H]
                s = sat.get(H, 1.0)
                l = 0.95 - (L / 15.0) * 0.90
                P[i] = hsl_to_rgb(h, s, l)

    P[0x00] = (255, 255, 255)
    P[0x5A] = (75, 0, 130)
    return P

5. 形象编号格式

5.1 格式

<作品>-<角色>-<特征串>

其中特征串固定为 7 位:

<发色><眼色><呆毛><耳><角>
 2位   2位   1位  1位 1位

完整形式:

BA-hina-5A5A7NR
│   │    │││││
│   │    ││││└── 角
│   │    │││└─── 耳
│   │    ││└──── 呆毛
│   │    │└───── 眼色
│   │    └────── 发色
│   └─────────── 角色
└─────────────── 作品

5.2 字段定义

字段 长度 字符集 含义
作品 可变 大写字母/数字 作品缩写,如 BA
角色 可变 小写字母/数字 角色罗马音,如 hina、hoshino
发色 2 0-9A-F 头发区域颜色摘要码
眼色 2 0-9A-F 眼睛区域颜色摘要码
呆毛 1 0-7 呆毛类别,共 8 类
耳 1 大写字母 耳特征
角 1 大写字母 角特征

5.3 已知取值

呆毛类别

值 含义
0~7 8 类呆毛,具体判定标准 TODO
已知 hina = 7

耳特征

值 含义
N 没有体现出耳朵
其他 TODO

角特征

值 含义
R 有环绕头部的角
N 没有角
其他 TODO

5.4 解析规则

  1. 以最后一个 - 为界,右侧为 7 位特征串;
  2. 特征串按位置解析:
    • 第 1~2 位:发色;
    • 第 3~4 位:眼色;
    • 第 5 位:呆毛;
    • 第 6 位:耳;
    • 第 7 位:角。
  3. 角色名不得包含 -。

6. 编码生成流程

  1. 确定作品与角色命名空间;
  2. 对头发区域执行第 3 节颜色摘要操作,得到发色码;
  3. 对眼睛区域执行第 3 节颜色摘要操作,得到眼色码;
  4. 判定呆毛类别,输出 0~7;
  5. 判定耳特征,输出对应字母;
  6. 判定角特征,输出对应字母;
  7. 拼接:
<作品>-<角色>-<发色><眼色><呆毛><耳><角>

7. 示例

7.1 空崎日奈

BA-hina-5A5A7NR

解析:

作品:BA
角色:hina
发色:5A = 深紫
眼色:5A = 深紫
呆毛:7 = 第7类
耳:N = 没有体现出耳朵
角:R = 有环绕头部的角

7.2 空崎日奈另一形象

BA-hina-005A7NR

解析:

发色:00 = 纯白
眼色:5A = 深紫
呆毛:7
耳:N
角:R

7.3 小鸟游星野(推测)

BA-hoshino-6A5A3NN

解析:

作品:BA
角色:hoshino
发色:6A = 推测粉色
眼色:5A = 推测蓝主导
呆毛:3 = 推测第3类
耳:N = 没有体现出耳朵
角:N = 没有角
注:6A、5A、3 为基于外观的推测,需实际运行算法确认。

8. 待定与扩展

  1. 呆毛 8 类 0~7 的判定标准;
  2. 耳特征完整取值表;
  3. 角特征完整取值表;
  4. 异色瞳处理策略:主导色、平均色或左右眼分字段;
  5. 调色板版本升级策略;
  6. 发色/眼色取样区域精确定义;
  7. 多部位扩展,如服装、装饰、光环等;
  8. 编号碰撞处理;
  9. 算法与调色板版本元数据。

9. 版本与元数据

本规范初稿绑定:

  • 调色板:PAL-16x16-v1
  • 颜色摘要算法:线性 RGB 平均 + 加权 RGB 最近邻
  • 轮廓去除默认:形态学腐蚀,宽度 (w=2)

若调色板或算法变更,应升级版本号,或重新生成全部形象编号。


规范初稿结束。

添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论