Skip to main content

Embedding-based image classification using FAISS and DashScope API.

Project description

nearest-image-class

基于嵌入向量(Embedding)和 FAISS 最近邻搜索的图像分类与检索工具包。底层调用 DashScope 通义千问视觉嵌入 API 生成图像向量,结合 FAISS 索引实现高效的相似度搜索与分类决策。

✨ 核心特性

  • 嵌入向量检索:基于 FAISS 实现高效的余弦相似度最近邻搜索,支持单条与批量查询。
  • 多模态嵌入模型:支持 DashScope 视觉嵌入模型,包括 tongyi-embedding-vision-flashtongyi-embedding-vision-plusqwen3-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 而非密码进行上传。

📝 注意事项

  • 确保项目根目录包含 LICENSEREADME.md,它们会被自动包含在分发包中。
  • 版本号由 nearest_image_class/_version.py 中的 __version__ 变量控制,例如:
    # nearest_image_class/_version.py
    __version__ = "0.1.0"
    
  • 每次上传 PyPI 前必须更新 __version__ 的值(PyPI 不允许重复版本号)。

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nearest_image_class-0.1.0.tar.gz (48.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nearest_image_class-0.1.0-py3-none-any.whl (53.5 kB view details)

Uploaded Python 3

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

Hashes for nearest_image_class-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a36194c5068b76405d4f7ef1e58535c9a9924cbf2cf74f55da9c866e99093333
MD5 66ea5fe054de5790218cc97b12635ec4
BLAKE2b-256 85aa8cc5de6026f3f59178ccc91b495bab9499ec6ef5b1267568a225e220e5cd

See more details on using hashes here.

File details

Details for the file nearest_image_class-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for nearest_image_class-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 41fe3a9d8a4e9df8191fa2c816f433f4b5f915aaf8870316495c18360394dad6
MD5 1e9738c43937dbf8fa08416aa526c3f7
BLAKE2b-256 ee8a809a31fcdc5a44456eebde0d0d5e75f18e8e05f6957e17155b71365b265c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page