吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 291|回复: 4
上一主题 下一主题
收起左侧

[Python 原创] 使用JINA和FAISS实现基于图像的文本语义检索和相似图像检索

  [复制链接]
跳转到指定楼层
楼主
mikemelon 发表于 2026-7-23 21:34 回帖奖励
本帖最后由 mikemelon 于 2026-7-23 21:42 编辑

[md]
图像语义搜索用到了JINA的最新开源大模型jina-embeddings-v5-text-small-retrieval,在HF上地址:
https://hf-mirror.com/jinaai/jina-embeddings-v5-omni-small-retrieval
它可以将文本、图像、视频或音频进行多模态嵌入到一个共享向量空间中,因此可以使用任何模态进行搜索。

下载该模型,需要先安装Python包huggingface-hub(我使用Python 3.9安装的是huggingface_hub的1.8.0):
[Bash shell] 纯文本查看 复制代码
pip install huggingface_hub==1.8.0


可以从hf-mirror镜像下载:
[Bash shell] 纯文本查看 复制代码
set HF_ENDPOINT=https://hf-mirror.com


huggingface_hub包带有hf.exe命令行工具,利用它将jina-embeddings-v5-text-small-retrieval模型下载到本地,
下载命令如下(为节省空间,不让它使用默认的下载路径,--local-dir就是设置到E:\Models\jina-embeddings-v5-omni-small-retrieval
[Bash shell] 纯文本查看 复制代码
hf download jinaai/jina-embeddings-v5-omni-small-retrieval --local-dir E:\Models\jina-embeddings-v5-omni-small-retrieval



等待下载完毕,全部目录所占空间不到3G。

提示:如果下载速度较慢,可以 到huggingface网站 https://huggingface.co/ 上注册,创建并复制Access Token,
然后用hf auth login命令,登录后填入该AccessToken,可加速。

由于该大模型本身并不支持索引,因此可用FAISS建立图像文件索引并保存在本地,如下是建立索引的build_index.py代码:
[Python] 纯文本查看 复制代码
from sentence_transformers import SentenceTransformer  
import torch  
from PIL import Image  
import numpy as np  
import faiss  
import pickle  
from pathlib import Path  
from tqdm import tqdm
  
LOCAL_MODEL_PATH = r"E:\Models\jina-embeddings-v5-omni-small-retrieval"  
  
try:  
    model = SentenceTransformer(  
        LOCAL_MODEL_PATH,  
        trust_remote_code=True,  
        model_kwargs={  
            "torch_dtype": torch.float16,  
        }  
    )  
    print(f"✅ 已从本地加载模型: {LOCAL_MODEL_PATH}")  
except Exception as e:  
    print(f"本地加载失败: {e}")  
    model = None  
  
# ================== 配置区域 ==================
search_folders = [  
    Path(r"E:\照片\小米手机导出"),  
    Path(r"E:\照片\饭饭照片\2016-05"),  
    Path(r"E:\图片\Camera"),
]  
  
image_extensions = {".jpg", ".jpeg", ".png", ".webp", ".bmp", ".tiff"}  
# =============================================  
  
embeddings = []  
metadata = []  
  
for folder in search_folders:  
    print(f"正在扫描: {folder}")  
    for img_path in tqdm(list(folder.rglob("*"))):  
        if img_path.suffix.lower() in image_extensions:  
            try:  
                # # 可选:跳过过大图片(防止内存爆炸)  
                # if img_path.stat().st_size > 20 * 1024 * 1024:  # >20MB  
                #     continue  
                img = Image.open(img_path).convert("RGB")  
                emb = model.encode(img, show_progress_bar=False)  
  
                embeddings.append(emb)  
                metadata.append({  
                    "path": str(img_path),  
                    "name": img_path.name,  
                    "folder": str(img_path.parent)  
                })  
            except Exception as e:  
                print(f"跳过损坏图片: {img_path} - {e}")  
  
# 建立索引  
embeddings = np.array(embeddings).astype('float32')  
faiss.normalize_L2(embeddings)  
  
index = faiss.IndexFlatIP(embeddings.shape[1])  
index.add(embeddings)  
  
# 保存  
faiss.write_index(index, "my_image_search.index")  
with open("image_metadata.pkl", "wb") as f:  
    pickle.dump(metadata, f)  
  
print(f"✅ 索引建立完成!共处理 {len(embeddings)} 张图片")


上面代码生成两个文件:
(1)my_image_search.index是FAISS索引文件
(2)image_metadata.pkl是图像的元数据(这里仅包括图像路径、文件名等信息)

建立索引的时间,我的机器上大概1到2秒一张图片,一开始建议可以先测试几个小的图片目录。



上述两个文件,可以用于后续搜索search.py程序:
[Python] 纯文本查看 复制代码
import faiss  
import pickle  
import numpy as np  
from sentence_transformers import SentenceTransformer  
from PIL import Image  
import torch  
  
# ================== 加载模型和文件 ==================
LOCAL_MODEL_PATH = r"E:\Models\jina-embeddings-v5-omni-small-retrieval"  
  
try:  
    model = SentenceTransformer(  
        LOCAL_MODEL_PATH,  
        trust_remote_code=True,  
        model_kwargs={  
            "torch_dtype": torch.float16,  
        }  
    )  
    print(f"✅ 已从本地加载模型: {LOCAL_MODEL_PATH}")  
except Exception as e:  
    print(f"本地加载失败: {e}")  
    model = None  
  
# 加载索引和元数据  
index = faiss.read_index("my_image_search.index")  
  
with open("image_metadata.pkl", "rb") as f:  
    metadata = pickle.load(f)  
  
print(f"索引加载成功!共 {len(metadata)} 张图片\n")  
  
  
# ================================================  
def search(query, k=5, is_image=False):  
    """查询函数"""  
    if is_image:  
        # # 图像查询  
        # img = Image.open(query).convert("RGB")  
        # query_emb = model.encode(img)        # print(f"使用图片查询: {query}")  
  
        # 图像查询  
        if isinstance(query, str):  # 如果传入的是路径  
            img = Image.open(query).convert("RGB")  
        else:  
            img = query.convert("RGB") if hasattr(query, "convert") else query  
  
        print(f"使用图片查询: {query}")  
        query_emb = model.encode([img], convert_to_numpy=True)[0]  
    else:  
        # 文本查询  
        query_emb = model.encode(query)  
        print(f"使用文本查询: {query}")  
  
    # 搜索  
    query_emb = np.array([query_emb]).astype('float32')  
    faiss.normalize_L2(query_emb)  
  
    distances, indices = index.search(query_emb, k)  
  
    print(f"\n找到 Top-{k} 结果:\n")  
    for i, (idx, score) in enumerate(zip(indices[0], 1-distances[0])):  
        meta = metadata[idx]  
        print(f"{i + 1}. 相似度: {score:.4f}")  
        print(f"   文件名: {meta['name']}")  
        print(f"   路径: {meta['path']}")  
        print("-" * 80)  
  
  
# ================== 使用示例 ==================  
# 示例1:文本搜索图片  
search("白色雪人", k=6)  
  
# 示例2:用图片搜索相似图片  
# search(r"C:\test\query.jpg", k=5, is_image=True)


上述程序支持两种方式搜索图片(如上代码最后的示例1和示例2):
(1)用文本描述搜索图片
(2)用图片搜索相似图片

其实,对于这个多模态嵌入大模型,还可以用音频、视频来搜索。

还可以给这俩个程序用Flask简单做个web网站,提供图片预览和下载,可能使用更方便些。
这里只是示意程序,且空间有限,就不再展示了,只给出几个运行结果截图。






免费评分

参与人数 5吾爱币 +5 热心值 +4 收起 理由
weidechan + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
laozhang4201 + 1 + 1 热心回复!
安尼大大 + 1 + 1 我很赞同!
DIYSS + 1 + 1 我很赞同!
Codeman + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
DIYSS 发表于 2026-7-24 01:29
这样也行
3#
安尼大大 发表于 2026-7-24 01:35
4#
weiliangshijiyi 发表于 2026-7-24 08:17
5#
linyun7570 发表于 2026-7-24 12:02
感谢分享,提取
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-7-24 23:29

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表