# 2026-08-29:图像类型分类 + 双鉴黄 方案 ## 目标 区分 **真人 / 动漫 / 风景** 三类图片,分别落不同目录;真人、动漫各用一套本地离线鉴黄, 命中的敏感图按**分值档**落到对应目录。全程本地运行,不依赖在线大模型。 ## 分类定义 | 类型 | 含义 | 敏感判定 | |------|------|----------| | 真人 | 真实照片且含人物 | NudeNet(现用,照片训练) | | 动漫 | 二次元/插画/3D 渲染 | wd14/danbooru 动漫鉴黄 | | 风景 | 真实照片无人物(纯场景) | 一般不做 | ## 模型选型(全部本地 ONNX) | 阶段 | 模型 | 说明 | |------|------|------| | 真人 vs 动漫 | `dghs-imgutils` `anime_real` | 二分类,输出 real/anime 概率 | | 真人 vs 风景 | 真人检测器 | 检测到人脸/人物 → 真人,否则风景 | | 真人鉴黄 | NudeNet(已有 `lib/320n.onnx`) | 保持现状 | | 动漫鉴黄 | `dghs-imgutils` `anime_rating` / `nsfw_pred` | danbooru 评级:safe/questionable/explicit 分数 | - `dghs-imgutils`(`pip install dghs-imgutils`)一个包覆盖「真人/动漫判定」+「动漫鉴黄」+「动漫分类」, 纯 ONNX、CPU、离线,与现有 NudeNet 同栈。 - 「真人 vs 风景」需真人检测器,可选: - YOLOv8n person(COCO,约 6MB):检测整个人,更符合「真人」语义 - RetinaFace 人脸(约 1.6MB):只认脸,快但漏掉没脸的人物照 ## 判定流程 ``` 图片 → ① anime_real 判定 ├─ 动漫 → ② 动漫鉴黄(anime_rating/nsfw_pred) → 分值 │ ├─ 正常 → 图片_动漫_方向_清晰度/明暗 │ └─ 敏感 → 图片_敏感_动漫_<分值档> └─ 真人 → ③ 真人检测器 ├─ 无人物 → 风景 → 图片_风景_方向_清晰度/明暗 └─ 有人物 → ④ NudeNet 鉴黄 ├─ 正常 → 图片_真人_方向_清晰度/明暗 └─ 敏感 → 图片_敏感_真人_<分值档> ``` ## 落地改动点 1. **`internal/nsfw/server.py`**:升级为「类型判定 + 双鉴黄」服务,`/detect` 返回 `{subject, isAnime, nsfwScore, nsfwType}`(或拆多个接口) 2. **`internal/classify`**:新增 subject 维度,拼目录名 `图片__方向_清晰度/明暗` 与 `图片_敏感__<分值档>` 3. **`internal/organize`**:probe 阶段收集 subject + 分值,分流到对应目录 4. **`internal/store` + 前端**:媒体库加「真人/动漫/风景」筛选;色情识别页面标注类型与分值 5. **`lib/`**:新增 imgutils 各模型 + 真人检测器模型(离线分发,同 `320n.onnx` 思路, 首次联网下载进 lib) ## 确认点(待用户拍板) 1. **「真人」判定标准**:检测到**人脸**就算(RetinaFace,轻量),还是要检测到**整个人** (YOLO person)?宠物/静物照片归哪类(风景 or 单独「其他」)? 2. **动漫风景**(二次元场景图)归「动漫」还是「风景」?(默认归「动漫」) 3. **目录结构**:普通图保持 `图片_<类型>_方向_清晰度/明暗`;敏感图用 `图片_敏感_<类型>_<分值档>`(分值档沿用 20/40/60/80/100 五档)。还是敏感图也要保留方向/明暗? 4. **动漫鉴黄阈值/等级**:`questionable`(擦边)和 `explicit`(露骨)都算敏感,还是只有 `explicit` 算? 5. **离线模型体积**:imgutils 各模型 + YOLO 合计约几十到几百 MB(wd14 动漫鉴黄模型较大), 需首次联网下载进 `lib/` 再分发——接受吗?还是改用更小的动漫鉴黄模型(精度略降)?