Embedding-based image classification using FAISS and DashScope API.
Project description
nearest-image-class
基于嵌入向量(Embedding)和 FAISS 最近邻搜索的图像分类与检索工具包。底层调用 DashScope 通义千问视觉嵌入 API 生成图像向量,结合 FAISS 索引实现高效的相似度搜索与分类决策。
✨ 核心特性
- 嵌入向量检索:基于 FAISS 实现高效的余弦相似度最近邻搜索,支持单条与批量查询。
- 多模态嵌入模型:支持 DashScope 视觉嵌入模型,包括
tongyi-embedding-vision-flash、tongyi-embedding-vision-plus和qwen3-vl-embedding。 - 持久化存储:使用 SQLite 持久化图像元数据与嵌入向量,支持增删改查与事务操作。
- 磁盘缓存:嵌入向量支持 NPZ 格式磁盘缓存,避免对重复图像重复调用 API。
- 分类策略:支持
TOP_1(最近邻类别)与MAJORITY_VOTE(多数投票)两种分类决策策略。 - 线程安全:FAISS 索引操作与数据库写操作均受可重入锁保护,支持并发场景。
- 配套工具脚本:提供 GUI 审核录入、批量分类、图片聚类、去重、缓存预生成等实用工具。
📁 项目结构
nearest_image_class/
├── components/
│ ├── image_embedding.py # 图像嵌入模型封装(DashScope API)
│ ├── faiss_manager.py # FAISS 向量索引管理器
│ └── sqlite_manager.py # SQLite 图像元数据管理器
├── tools/
│ ├── checker_plus.py # GUI 图片审核录入工具
│ ├── classify_imgs.py # 批量图片分类工具
│ ├── cluster_imgs.py # 图片相似度聚类工具
│ ├── dedup_imgs.py # 图片相似度去重工具
│ └── create_embedding_cache_file.py # 预生成嵌入向量缓存
├── image_search_classifier.py # 核心分类器(ImageSearchClassifier)
├── utils.py # 图像读取、编码、路径处理等通用工具
├── __init__.py
└── _version.py
🛠️ 环境要求
- Python >= 3.10
- Conda 或 venv 虚拟环境(推荐)
主要依赖:numpy, opencv-python, pillow, faiss-cpu, dashscope, loguru, tqdm, xxhash
📦 安装
1. 创建并激活 Conda 虚拟环境(推荐)
conda create -n nearest_image_class_env python=3.10 -y
conda activate nearest_image_class_env
2. 开发模式安装(可编辑安装)
适用于开发阶段,代码修改后无需重新安装即可生效:
pip install -e .
3. 普通安装(从源码安装)
pip install .
🚀 快速使用
初始化分类器
from nearest_image_class.image_search_classifier import ImageSearchClassifier, ClassificationStrategy
from loguru import logger
classifier = ImageSearchClassifier(
data_dir="./data", # 数据根目录
model_name="tongyi-embedding-vision-flash-2026-03-06", # 嵌入模型
api_key="your-dashscope-api-key", # DashScope API 密钥
dimension=768, # 嵌入向量维度
batch_size=20, # 批量处理大小
max_image_size=2048, # 图像长边最大尺寸
max_workers=8, # 并发线程数
similarity_threshold=0.8, # 分类相似度阈值
strategy=ClassificationStrategy.TOP_1, # 分类策略
top_k=5, # 最近邻返回数量
cache_file_path="./cache/embeddings.npz", # 嵌入缓存路径(可选)
logger=logger,
)
单张图像分类
result = classifier.classify("path/to/image.jpg")
print(result) # 输出预测的类别标签,若无可信结果则返回 None
批量图像分类
images = ["path/to/img1.jpg", "path/to/img2.jpg"]
predictions = classifier.batch_classify(images)
print(predictions)
批量相似度搜索
results_list = classifier.batch_search(images)
for results in results_list:
for res in results:
print(f"路径: {res.relative_image_path}, 类别: {res.category}, 相似度: {res.similarity_score:.4f}")
增量添加图片
向已有数据库中增量添加单张图片,自动更新索引,无需触发全量 rebuild:
record_id = classifier.add_image("path/to/new_image.jpg", category="phone_case")
print(f"新增记录 ID: {record_id}")
相似度搜索
results = classifier.search("path/to/image.jpg")
for res in results:
print(f"路径: {res.relative_image_path}, 类别: {res.category}, 相似度: {res.similarity_score:.4f}")
释放资源
classifier.close()
📂 数据目录约定
分类器要求图像数据按以下目录结构组织:
{data_dir}/
├── images/
│ ├── category_a/
│ │ ├── img_001.jpg
│ │ └── img_002.png
│ └── category_b/
│ └── img_003.jpg
└── images.db # SQLite 数据库(自动创建)
{data_dir}/images/{category}/为图像存储路径,子目录名为类别标签。images.db为自动创建的 SQLite 数据库,用于持久化图像路径、类别和嵌入向量。- 初始化时会自动扫描
images/目录,同步数据库并重建 FAISS 索引。
🧰 工具脚本
checker_plus.py — GUI 图片审核录入工具
提供图形化界面进行图片审核:
- 左侧展示待审核图片列表,中间为图片预览
- 右侧实时显示相似图片推荐(Top-K 最近邻)
- 支持分类录入、忽略、一键忽略高相似度图片
- 自动检测疑似重复图片(相似度 ≥ 阈值时标记为不推荐录入)
from tkinter import Tk
from nearest_image_class.tools.checker_plus import ImageReviewTool
root = Tk()
app = ImageReviewTool(
root=root,
data_dir="./data",
model_name="tongyi-embedding-vision-flash-2026-03-06",
api_key="your-api-key",
dimension=768,
batch_size=20,
max_image_size=2048,
max_workers=1,
top_k=5,
duplicate_threshold=0.97,
similarity_threshold=0.8,
cache_file_path="./cache/embeddings.npz",
)
root.mainloop()
classify_imgs.py — 批量图片分类
对输入目录下的图片进行批量分类,按类别输出到子目录:
from nearest_image_class.tools.classify_imgs import classify_imgs
classify_imgs(
input_dir="./待分类图片",
output_dir="./分类结果",
data_dir="./data",
model_name="tongyi-embedding-vision-flash-2026-03-06",
api_key="your-api-key",
dimension=768,
batch_size=20,
max_image_size=2048,
strategy="top_1", # 或 "majority_vote"
similarity_threshold=0.8,
)
dedup_imgs.py — 图片相似度去重
对输入目录内的图片进行全局去重,保留的图片输出到指定目录,重复图片可单独存放:
from nearest_image_class.tools.dedup_imgs import dedup_imgs
dedup_imgs(
input_dir="./待去重图片",
output_dir="./去重后",
duplicate_dir="./重复图片", # 可选
model_name="tongyi-embedding-vision-flash-2026-03-06",
api_key="your-api-key",
dimension=768,
similarity_threshold=0.95, # 去重阈值
)
cluster_imgs.py — 图片相似度聚类
对输入目录内的图片按相似度自动聚类,相似图片归入同一 cluster_xxx 目录,孤立的图片放入 未分类:
from nearest_image_class.tools.cluster_imgs import cluster_imgs
cluster_imgs(
input_dir="./待聚类图片",
output_dir="./聚类结果",
model_name="tongyi-embedding-vision-flash-2026-03-06",
api_key="your-api-key",
dimension=768,
batch_size=20,
max_image_size=2048,
similarity_threshold=0.85, # 聚类相似度阈值
min_cluster_size=1, # 最小聚类大小
)
create_embedding_cache_file.py — 预生成嵌入缓存
从指定目录批量生成图片嵌入向量并保存为 NPZ 缓存文件,便于后续重复使用:
from nearest_image_class.tools.create_embedding_cache_file import create_embedding_cache_file
create_embedding_cache_file(
image_dir="./图片目录",
cache_file_path="./cache/embeddings.npz",
api_key="your-api-key",
model_name="tongyi-embedding-vision-flash-2026-03-06",
dimension=768,
)
⚙️ 配置参数说明
| 参数 | 说明 | 典型值 |
|---|---|---|
data_dir |
数据根目录 | "./data" |
model_name |
DashScope 嵌入模型名称 | "tongyi-embedding-vision-flash-2026-03-06" |
dimension |
嵌入向量维度 | 768(flash)、1024(plus) |
batch_size |
API 批量处理大小 | 20(flash/plus)、1(qwen3-vl) |
max_image_size |
图像预处理时长边最大尺寸 | 2048 |
max_workers |
并发线程数 | 8 |
similarity_threshold |
分类/去重相似度阈值 | 0.8(分类)、0.95(去重) |
top_k |
最近邻搜索返回结果数 | 5 |
strategy |
分类策略 | "top_1" / "majority_vote" |
cache_file_path |
嵌入向量缓存文件路径(NPZ) | "./cache/embeddings.npz" |
🏗️ 构建分发包
首先安装构建工具:
pip install build
然后在项目根目录运行:
python -m build
构建完成后,dist/ 目录将包含两个文件:
nearest_image_class-<VERSION>.tar.gz(源码分发包,sdist)nearest_image_class-<VERSION>-py3-none-any.whl(二进制分发包,wheel)
✅ 推荐始终通过
python -m build构建,而非直接调用setup.py。
📤 上传到 PyPI
步骤 1:安装上传工具
pip install twine
步骤 2:验证分发包(可选但推荐)
twine check dist/*
步骤 3:上传到 TestPyPI(测试)
twine upload --repository testpypi dist/*
需要 TestPyPI 账号。
步骤 4:上传到正式 PyPI
twine upload dist/*
需要 PyPI 账号 并配置 API Token(推荐使用
__token__作为用户名)。
🔐 安全提示:建议使用 API Token 而非密码进行上传。
📝 注意事项
- 确保项目根目录包含
LICENSE和README.md,它们会被自动包含在分发包中。 - 版本号由
nearest_image_class/_version.py中的__version__变量控制,例如:# nearest_image_class/_version.py __version__ = "0.1.0"
- 每次上传 PyPI 前必须更新
__version__的值(PyPI 不允许重复版本号)。
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nearest_image_class-0.1.0.tar.gz.
File metadata
- Download URL: nearest_image_class-0.1.0.tar.gz
- Upload date:
- Size: 48.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a36194c5068b76405d4f7ef1e58535c9a9924cbf2cf74f55da9c866e99093333
|
|
| MD5 |
66ea5fe054de5790218cc97b12635ec4
|
|
| BLAKE2b-256 |
85aa8cc5de6026f3f59178ccc91b495bab9499ec6ef5b1267568a225e220e5cd
|
File details
Details for the file nearest_image_class-0.1.0-py3-none-any.whl.
File metadata
- Download URL: nearest_image_class-0.1.0-py3-none-any.whl
- Upload date:
- Size: 53.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
41fe3a9d8a4e9df8191fa2c816f433f4b5f915aaf8870316495c18360394dad6
|
|
| MD5 |
1e9738c43937dbf8fa08416aa526c3f7
|
|
| BLAKE2b-256 |
ee8a809a31fcdc5a44456eebde0d0d5e75f18e8e05f6957e17155b71365b265c
|