Skip to content

LMFrank/bird-mvp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

灵羽图库 (Bird MVP) v0.1.6

这是一个本地运行的 Web 应用:前端用于快速浏览/筛选/打标,后端负责扫描目录、生成缩略图缓存、SQLite 持久化;并通过一个本地 AI 服务进行鸟种识别(BioCLIP2)。

一句话启动及使用

# 1. 启动服务(首次需构建)
docker compose up --build -d

# 2. 生成全球全量鸟种标签(推荐,大幅提高识别率;已生成可跳过)
npm run labels:world && docker compose restart ai

# 3. 浏览器访问:http://localhost:3001
# 4. 在页面添加库路径 /photos 并扫描 -> 识别(如需覆盖重跑,点“重识别”)
# 5. 如需清除识别结果:支持单张清除(详情页垃圾桶)与按库一键清除(顶部“清除识别”)

Docker 部署(推荐)

1) 配置镜像源(Docker Desktop)

使用开源镜像站搜索镜像:https://docker.aityp.com/ 本项目dockerfile已直接添加国内镜像源,无需额外配置。

2) 启动

在项目根目录:

docker compose up --build -d

打开:http://localhost:3001/

可选:用 make 简化常用命令

如果你本机有 GNU Make(例如 macOS/Linux,或 Windows 的 Git Bash/MSYS2),可以直接:

make help
make up
make logs
make ai-health
make data-clean

3) 添加你的照片目录

容器内默认挂载了 ./sample-photos/photos。你可以在页面里新增库路径为:/photos,然后点击“扫描”。 仓库内的 sample-photos 默认只保留少量示例图片。

如果要换成你自己的目录,请修改 docker-compose.ymlapp.volumes,把宿主机目录挂载到容器(示例):

volumes:
  - D:/BirdJpg:/photos:ro

然后在页面新增库路径填:/photos

鸟种识别(BioCLIP2)

默认内置了少量常见鸟示例标签,用于验证链路。你可以通过 BIRD_LABELS_PATH 提供一个 CSV,格式为:

中文名,学名
麻雀,Passer montanus
喜鹊,Pica pica

将该 CSV 挂载进 ai 容器并设置环境变量即可。

识别方式(输入与裁剪)

识别时并不是直接把原图丢给 AI,而是由后端先生成“识别专用图片”,再调用 AI 服务:

  • 输入图片:从原图生成 JPEG(默认最大边 4096、质量 90),用于尽量保留细节
  • 多裁剪(单张识别默认开启):全图 + 多个方形裁剪分别识别,再把结果融合(同一物种取各次识别中的最高分)
  • 批量识别:默认只跑全图(更快);可通过环境变量开启多裁剪

识别入口:

  • 单张识别:详情页点击“识别”
  • 批量识别:库顶部点击“一键识别”(覆盖重跑用“重识别”)

识别输入调优(可选)

识别输入调优支持两种方式:

  • 推荐:页面顶部“调优”面板修改(保存到本地 SQLite,立即生效)

  • 环境变量:设置在 app 服务(Docker 在 docker-compose.yml;本地开发写入 .env

  • IDENTIFY_MAX_SIZE:识别输入最大边(默认 4096,范围 512–8192)

  • IDENTIFY_JPEG_QUALITY:识别输入 JPEG 质量(默认 90,范围 30–100)

  • IDENTIFY_CROPS_SINGLE:单张识别裁剪次数(默认 9,范围 1–9)

  • IDENTIFY_CROPS_BATCH:批量识别裁剪次数(默认 3,范围 1–9)

  • IDENTIFY_CROP_SCALES_SINGLE / IDENTIFY_CROP_SCALES_BATCH:多尺度裁剪(逗号分隔,范围 0.35–0.9;例如 0.6,0.45

Docker 示例(修改 docker-compose.ymlapp.environment):

environment:
  - IDENTIFY_MAX_SIZE=4096
  - IDENTIFY_JPEG_QUALITY=90
  - IDENTIFY_CROPS_SINGLE=9
  - IDENTIFY_CROPS_BATCH=3
  - IDENTIFY_CROP_SCALES_SINGLE=0.6,0.45
  - IDENTIFY_CROP_SCALES_BATCH=0.6,0.45

识别率不理想时的排查顺序:

  • 先看 AI 候选集是否正确:打开 http://localhost:3001/api/ai/health,确认 labels 数量与预期一致
  • 再看图片是否“小鸟占比太低”:优先用单张识别(默认多裁剪)验证效果;必要时提高 IDENTIFY_CROPS_SINGLE 或调大 IDENTIFY_CROP_SCALE
  • 仍不理想:增大 IDENTIFY_MAX_SIZE(例如 6144)或提高 IDENTIFY_JPEG_QUALITY(例如 95)

低置信度兜底(可选:多模态大模型)

当离线模型识别“置信度不高”(Top1 分数低或 Top1-Top2 间隔小)时,后端可选地调用多模态大模型对“候选 TopK”做一次兜底判断,并把结果展示在详情页的“兜底”区域。

说明:

  • 兜底只会在离线模型给出的候选 TopK 里做选择,避免大模型乱猜
  • 开启后会产生联网请求与费用
  • 推荐用页面顶部“调优”面板启用并填写 Key(Key 存本地 SQLite,不会回显也不会写回 .env

用环境变量配置(参考 .env.example):

# Qwen (DashScope OpenAI 兼容模式;模型需支持图片输入,通常为 *vl* 系列)
QWEN_API_KEY=你的 key
QWEN_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
QWEN_MODEL_NAME=qwen-vl-plus

# 可选:触发阈值(默认与前端提示一致)
LLM_FALLBACK_TRIGGER_SCORE=0.6
LLM_FALLBACK_TRIGGER_MARGIN=0.1

获取“全量中国鸟种”CSV(推荐:eBird API 自动生成)

项目内置了一个脚本,使用 eBird API 拉取「中国(CN)区域曾记录的物种代码」+「eBird taxonomy(支持中文 locale)」并生成 data/models/labels.csv

说明:eBird API 大多数接口需要 API Key,并通过请求头 x-ebirdapitoken 传入。参考 eBird 官方 API 文档:https://documenter.getpostman.com/view/664302/S1ENwy59

  1. 生成 eBird API Key(登录 eBird 后在 Keygen 页面生成)

  2. 在项目根目录运行(PowerShell):

$env:EBIRD_API_KEY = "你的 key"
npm run labels:cn

或者直接在.env添加key:

EBIRD_API_KEY=你的 key

成功后会生成:data/models/labels.csv(容器内对应 /models/labels.csv),重启 AI 容器即可生效:

docker compose up -d --force-recreate ai

说明:默认不再把 AI 服务端口暴露到宿主机(避免 Windows 端口占用/权限问题);应用容器通过 http://ai:8000 在 Docker 网络内访问即可。

无 GPU / 强制 CPU

如果你的 Docker 环境没有可用的 NVIDIA GPU:

  1. docker-compose.ymlai.environment 里加:FORCE_CPU=1

  2. 删除或注释 ai.gpus: all

识别报错 fetch failed / AI 不可用

优先打开后端探测接口查看更具体的原因:

  • http://localhost:3001/api/ai/health

常见原因:

  • BIRD_AI_URL 配置不正确:容器内通常是 http://ai:8000;宿主机本地运行则应使用可访问的地址(例如 http://localhost:8000
  • ai 容器未启动或启动失败:尤其是在没有 NVIDIA GPU 的环境中,需按上面的“强制 CPU”处理
  • ai 容器刚启动/重启:模型在加载期会短暂返回 loading,等几十秒后再重试即可

ROI 目标检测裁剪(默认开启,提升识别率)

为提升“小鸟占比低/主体不居中”的识别率,ai 服务内置了目标检测(YOLO)来自动找鸟并裁剪后再做 BioCLIP 识别;若检测不到,也会对全图做少量方形裁剪兜底。

默认行为:

  • 后端默认只发送 1 张全图给 ai(更快)
  • ai 服务在内部做检测与多裁剪融合(更像 superpicky 的效果)

可选环境变量(配置在 ai 服务):

  • DETECT_ENABLED:是否启用检测(默认 1
  • DETECT_MODEL:检测模型(默认 yolov8n.pt
  • DETECT_CONF:检测阈值(默认 0.25
  • DETECT_CLASS_ID:检测类别(默认 14,COCO 的 bird)
  • DETECT_MAX_CROPS:检测到目标后最多跑几张裁剪(默认 3
  • DETECT_FALLBACK_CROPS:检测不到时是否做兜底裁剪(默认 1
  • DETECT_FALLBACK_MAX:兜底裁剪最多跑几张(默认 4

建议先打开健康检查确认检测是否启用与是否报错:

  • http://localhost:3001/api/ai/health(会返回 detectEnabled/detectError)

识别非中国鸟类(例如金刚鹦鹉):生成“全球鸟种”CSV

如果你的照片里包含明显不属于中国鸟类范围的物种(例如金刚鹦鹉),只生成中国(CN)物种标签会导致模型“只能在 CN 候选里硬猜”,结果会很不对。

可以用脚本生成全量 eBird taxonomy(全球物种)作为候选集:

npm run labels:world

然后在页面里点击“重识别”(覆盖重跑),让已有照片按新标签集重新识别。

可选参数:

  • --region:默认 CN(中国);也可以用 eBird 的其它 regionCode
  • --locale:默认 zh_CN(中文)

脚本位置:scripts/ebird_labels.mjs

本地开发(非 Docker)

npm install
npm run dev

环境变量建议使用 .env(参考 .env.example),不要把真实 key 提交到仓库。

前端:http://localhost:5173/(代理到后端) 后端:http://localhost:3001/

数据与迁移(重要)

  • SQLite 存储位置:由 CACHE_DIR 决定,默认是 data/cache(库文件为 catalog.sqlite
  • 数据库 schema 通过 migrations 管理:启动时自动执行 server/migrations/*.sql(或 MIGRATIONS_DIR 指定目录),并记录到 schema_migrations
  • 批量识别任务状态已持久化到 SQLite 的 jobs 表(用于轮询与取消)
  • 任务并发:用 JOB_CONCURRENCY 控制同时运行的任务数(默认 1,建议保持 1 避免把 IO/AI 打满)
  • 生成数据不进仓库:data/cachedata/models 等为运行产物/模型与标签缓存,默认已加入 .gitignore

代码组织(后端)

后端约定为:

  • server/routes:只做 HTTP 适配(解析参数/返回响应),不要写 SQL/文件系统/AI 调用细节
  • server/services:业务编排(“扫描库”“识别单张/批量”等)
  • server/repos:SQL 与数据访问
  • server/lib:基础设施与通用工具(AI client、缩略图、migrations、校验/错误等)

更新记录

v0.1.5

  • 右侧详情面板增强:结构化文件信息 + EXIF(相机/镜头/焦距/光圈/快门/ISO 等)
  • EXIF 提取与缓存:点开照片自动回填,失败会在顶部错误条提示原因
  • 美学分批量回填与实时刷新:解决“只有第一张有分”的体验问题
  • 扫描去重修复:按路径/指纹合并并清理重复记录,避免列表出现重复照片
  • 鸟种识别增强:AI 服务增加 ROI 目标检测裁剪与兜底多裁剪,提高识别率

v0.1.4

  • 增加低置信度兜底配置与调优面板
  • 修复兜底 Key 优先级与失败原因展示
  • 修复单张清除后立即识别的竞态问题

v0.1.3

  • 识别输入升级:从原图生成识别专用 JPEG(默认 4096px / Q90),提升细节保留
  • 多裁剪识别:单张识别默认开启“全图 + 多位置裁剪”并融合结果,提高小目标命中率
  • 新增识别输入参数:支持通过环境变量调节输入尺寸、质量与裁剪策略
  • 后端架构调整:routes/services/repos 分层,SQLite schema 引入 migrations,批量识别任务状态持久化并支持并发控制

About

网页端AI识别鸟类照片软件

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors