feat: 二次元识别功能 + 模型目录整理(nwfs/wd-tagger 子目录),修复 wd-tagger 输入维度(NHWC)

This commit is contained in:
2025-06-25 21:10:21 +08:00
parent 4efa48f550
commit 3af2bf70b4
18 changed files with 1386 additions and 21 deletions
+39
View File
@@ -24,6 +24,7 @@ import (
"time"
"kenaito-media-picker/internal/config"
"kenaito-media-picker/internal/hentai"
"kenaito-media-picker/internal/nsfw"
"kenaito-media-picker/internal/organize"
"kenaito-media-picker/internal/probe"
@@ -76,6 +77,9 @@ const ConfigKeyDestDir = "scan.destDir"
// 配置开了但检测器没起来(没装 python/模型下载失败等)也能区分出来,前端据此提示。
const nsfwDetectorReadyKey = "nsfw.detectorReady"
// hentaiDetectorReadyKey 记录最近一次扫描时二次元检测服务是否真的起来了。
const hentaiDetectorReadyKey = "hentai.detectorReady"
// setNsfwDetectorReady 把"色情检测服务是否真的起来了"记进数据库(AppConfig)。
func (s *ScanService) setNsfwDetectorReady(ready bool) {
if s.store == nil {
@@ -88,6 +92,18 @@ func (s *ScanService) setNsfwDetectorReady(ready bool) {
_ = s.store.SaveConfig(nsfwDetectorReadyKey, v)
}
// setHentaiDetectorReady 把"二次元检测服务是否真的起来了"记进数据库(AppConfig)。
func (s *ScanService) setHentaiDetectorReady(ready bool) {
if s.store == nil {
return
}
v := "0"
if ready {
v = "1"
}
_ = s.store.SaveConfig(hentaiDetectorReadyKey, v)
}
// DefaultPickerDirName 用户没指定存放目录时,默认在扫描目录下新建这个文件夹装整理好的文件。
const DefaultPickerDirName = "KMP已整理"
@@ -533,8 +549,31 @@ func (s *ScanService) runScan(ctx context.Context, rootDir, destDir string) erro
}
}
// ---------- 第六步(可选):二次元识别 ----------
// 用本机 python + wd-tagger 起一个本地检测服务。没装依赖时跳过,
// 不影响图片整理——检测结果只决定走普通目录还是「图片_二次元」目录。
hentaiDet := (*hentai.Detector)(nil)
s.setHentaiDetectorReady(false)
if cfg := config.GetAppConfig(); cfg.HentaiEnabled {
if d, err := hentai.Start(cfg.HentaiPython, cfg.HentaiThreshold); err != nil {
fmt.Printf("=== 二次元识别未启用(图片照常处理): %v\n", err)
} else {
hentaiDet = d
defer hentaiDet.Stop()
s.setHentaiDetectorReady(true)
fmt.Println("=== 二次元识别已启用(wd-tagger)")
// 清掉上一次的二次元识别记录,保证「二次元识别」页面显示的是本次扫描的结果
if s.store != nil {
if err := s.store.ClearHentai(); err != nil {
fmt.Printf("=== 清空旧二次元识别记录失败: %v\n", err)
}
}
}
}
org := organize.New(pickerDir, ffprobePath, ffmpegPath, s.store, ctx)
org.SetNSFWDetector(nsfwDet)
org.SetHentaiDetector(hentaiDet)
org.SetRotateImages(config.GetAppConfig().RotateImages)
// 整个"整理"分两个阶段,界面上共用一条进度条: