Skip to main content

moxuan — 照片查重清理工具(v0.1.0)

识别近重复照片(连拍、同场景短间隔、轻微构图调整)并推荐每组保留最优的一张。

  • 一键清理流程:scan(扫描→特征→聚类→评分)→ groups 审核 → quarantine 隔离(可还原)→ purge 彻底删除
  • 网页审核界面:分组浏览 / 大图对比 / 手动改标最优 / 批量移入隔离区
  • 可配置:相似度阈值、时间窗、评分权重(config.toml + 网页设置面板)
  • 支持 RAW(CR2/NEF/ARW/RAF/DNG):内嵌预览参与查重/评分,大图按需 demosaic(3200px 或全尺寸)

安装

任选一种,均无需手动激活虚拟环境;首次运行自动下载模型(DINOv2 权重约 90MB + 人脸/BRISQUE 模型,缓存在 ~/.cache/moxuan/):

# 方式一:uvx 即用即走(推荐,零安装)
uvx moxuan scan <照片目录> --threshold 0.88

# 方式二:uv tool 全局安装(一次安装,命令常驻 PATH)
uv tool install moxuan

# 方式三:pip 直接安装(常规 Python 环境)
pip install moxuan
  • 人脸眼睛睁开检测默认不装,需要时用 [face] extra:uv tool install "moxuan[face]"(uvx 加 --extra face)
  • 源码开发(改网页前端时需要):
git clone https://ifilevault.myasustor.com:3101/mohoutech/moxuan
cd moxuan
uv venv --python 3.13
uv pip install -e ".[face]"

使用(CLI)

uvx 用户把下面的 moxuan 换成 uvx moxuan:

moxuan models                                  # (可选)预置模型,scan 会自动补齐
moxuan scan <照片目录> --threshold 0.88         # 一键全流程:扫描→特征→聚类→评分
moxuan groups                                  # 查看分组
moxuan report --format html                    # 生成 HTML/CSV 审核报告
moxuan quarantine <group_id>                   # 确认组清理:保留最优,其余移入隔离区
moxuan restore <quarantine_id>                 # 还原隔离区照片
moxuan purge <quarantine_id>                   # 彻底删除(不可恢复)
moxuan restore --prune                         # 清理手动删除 quarantine/ 后的失效记录

--threshold 为相似度阈值(默认 0.88,见 config.toml)。

网页审核界面

moxuan serve start    # 打开 http://localhost:9100(前端后端一体)
moxuan serve status   # 查询状态
moxuan serve stop     # 停止服务

安装版(pip/uvx)的网页界面已内置在 wheel,由后端同一端口(默认 9100)提供;开发模式则双进程:后端 9100 + 前端 Vite cd ui && npm run dev(5173,/api 代理到 9100;npm 缓存目录无写权限报 EPERM 时加 --cache 参数规避)。

  • 工作台:顶部展示当前工作路径,输入照片目录后依次执行 扫描→特征→聚类→评分(实时进度);任务记录可单条删除或一键清空已完成;照片全库统一聚类/评分,换目录前先「重置数据」清空旧照片,避免多目录混在一起
  • 审核:分组列表按 张数/最佳评分/拍摄时间 排序;网格滑块调尺寸(56–380px,默认 176px);悬停勾选可批量移入隔离区;点照片看大图(←/→ 翻页、Esc 关闭、可直接 设为最优/移出组),RAW 可「加载全尺寸」
  • 清理区:还原或彻底删除(与审核页同套网格/大图)
  • 设置:调整阈值/时间窗/评分权重

API

FastAPI REST 接口(api/routes.py):

  • POST /api/tasks/{scan|embed|cluster|score}、GET /api/tasks[/{id}]:任务执行与进度;DELETE /api/tasks[/{id}]:删除记录 / 清空全部已完成(运行中的不可删);DELETE /api/data:清空照片与分组(换目录重新开始)
  • GET /api/groups、GET /api/photos?group_id=:分组与照片
  • GET /api/thumbnail/{photo_id}、GET /api/original/{photo_id}:缩略图与原图(ETag/304 缓存);浏览器可解码格式直出原图,RAW 渲染缓存 JPEG(默认 3200px,?full=1 全尺寸)
  • PATCH /api/groups/{id}/best、POST /api/groups/{id}/{remove|restore}:设最优 / 移出组 / 移回组
  • GET /api/quarantine、POST /api/quarantine/confirm、POST /api/quarantine/{id}/restore、DELETE /api/quarantine/{id}:隔离区
  • GET|PATCH /api/settings:运行参数

.thumbnails/ 是可丢弃缓存(删后自动重建):缩略图 {id}.jpg;不可解码原图(如 TIFF)与 RAW 大图为 {id}_hires.jpg(3200px),RAW 全尺寸为 {id}_full.jpg。

配置

config.toml(项目根)是配置入口,环境变量 MOXUAN_CONFIG 可指定其他路径:

  • [service] host / port:网页服务监听地址与端口
  • [algorithm] threshold / window:相似度阈值(默认 0.88)与时间窗(默认 300s)
  • [algorithm.weights]:评分权重(清晰度/锐度/人脸/曝光/裁剪/对比度/动态范围/色彩/噪点/BRISQUE/EXIF)

网页「设置」面板的修改存数据库、优先于配置文件。安装版数据(用户 config、SQLite、日志、PID、隔离区)位于 Windows %APPDATA%\moxuan、Linux/macOS ~/.config/moxuan(MOXUAN_DATA 可重定向)。

算法

  • 相似度:DINOv2 embedding + 时间窗分桶(默认 300s;无 EXIF 时间单独互比)+ 余弦阈值连通分量 + SSIM 边界复核
  • 选优:清晰度 / 曝光 / 人脸(YuNet+眼睛睁开)/ BRISQUE / EXIF(分辨率/ISO/快门)加权评分
  • 清理安全:确认后移入隔离区,可还原;purge 彻底删除

环境要求

  • Python 3.11+(uv 自动下载所需版本)
  • 首次运行联网下载模型(moxuan models 可预置);Python 访问 github.com 超时时自动改用 curl
  • 运行时依赖:torch、opencv-contrib-python-headless、numpy、rawpy、Pillow、click、fastapi、uvicorn;可选 mediapipe([face])

发布(PyPI)

python scripts/build_frontend.py   # 构建前端到 api/web/(发布者需 node/npm)
uv build                           # 生成 sdist + wheel 到 dist/
uv publish                         # 需 UV_PUBLISH_TOKEN(PyPI API token)

测试

uv venv --python 3.13
uv pip install -e ".[dev]"
uv run pytest

Metadata

Release files for moxuan 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for moxuan 0.1.0
File Size Uploaded
moxuan-0.1.0.tar.gz 3.8 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for moxuan 0.1.0
File Interpreter ABI Platform
moxuan-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 7.7 MB

Release files / moxuan-0.1.0.tar.gz

Download URL moxuan-0.1.0.tar.gz
Size 3.8 MB
Tags Source
SHA-256 checksum
How to use checksums
d36c7c36aab4a45b42e32a5f56c80852559dead5d53e0e9998fef1b5eab22dfb
BLAKE2b-256 checksum
How to use checksums
09cfd49836f35d1f4aba75f07af95b604046fae91e7fe8b8731332348dcf389e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / moxuan-0.1.0-py3-none-any.whl

Download URL moxuan-0.1.0-py3-none-any.whl
Size 3.8 MB
Tags Python 3
SHA-256 checksum
How to use checksums
e858e93b289e05d8424789bf52c31279fa07f7fd066f64eaa8db8d4217b20c78
BLAKE2b-256 checksum
How to use checksums
0d8330fc5395b0f36c26a19d569b53a198359c7d0788d94c7985db381ab069d2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page