python+milvus实现一个以图搜图系统

文章介绍了如何搭建一个个人的以图搜图系统,包括使用Docker-compose安装Milvus,通过Python集成Towhee和ResNet50模型提取特征向量,将数据存储到Milvus,以及启动后端Python服务和前端展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言

当您听到“以图搜图”时,是否首先想到了百度、Google 等搜索引擎的以图搜图功能呢?事实上,您完全可以搭建一个属于自己的以图搜图系统:自己建立图片库;自己选择一张图片到库中进行搜索,并得到与其相似的若干图片。

说明

大概需要三个步骤

  1. 准备数据
  2. 训练数据
  3. 查询数据

准备数据

在这里插入图片描述
在这里插入图片描述

训练数据

在这里插入图片描述

训练数据的步骤这里是用了python方式集成towhee使用resnet50模型训练提出特征向量,存储到milvus,技术背景自行去了解,本文只整理操作步骤

安装minlvus(docker-compose方式)

1)、下载docker-compose.yml

wget https://github.com/milvus-io/milvus/releases/download/v2.1.4/milvus-standalone-docker-compose.yml -O docker-compose.yml

2)、docker启动docker-compose

docker-compose up -d

启动成功会显示

Creating milvus-etcd  ... done
Creating milvus-minio ... done
Creating milvus-standalone ... done

查询容器状态

docker-compose ps
      Name                     Command                  State                            Ports
--------------------------------------------------------------------------------------------------------------------
milvus-etcd         etcd -advertise-client-url ...   Up             2379/tcp, 2380/tcp
milvus-minio        /usr/bin/docker-entrypoint ...   Up (healthy)   9000/tcp
milvus-standalone   /tini -- milvus run standalone   Up             0.0.0.0:19530->19530/tcp, 0.0.0.0:9091->9091/tcp

觉得不清楚的可以参考官方文档
https://milvus.io/docs/v2.1.x/install_standalone-docker.md

python集成milvus+towhee

官方项目Demo包含前后端,其中后端python实现,前端演示react实现
https://github.com/milvus-io/bootcamp/tree/master/solutions/image/reverse_image_search/one_step

提取特征向量的核心代码

import towhee
from towhee.functional.option import _Reason

class ResNet50:
    def __init__(self):
        self.pipe = (towhee.dummy_input()
                    .image_decode()
                    .image_embedding.timm(model_name='resnet50')
                    .tensor_normalize()
                    .as_function()
        )
      
    def resnet50_extract_feat(self, img_path):
        feat = self.pipe(img_path)
        if isinstance(feat, _Reason):
            raise feat.exception
        return feat


if __name__ == "__main__":
    ResNet50().resnet50_extract_feat('https://github.com/towhee-io/towhee/raw/main/towhee_logo.png')

python后端启动方式

启动之前,首先修改config.py,将host修改成自己部署milvus服务器的host

MILVUS_HOST = os.getenv("MILVUS_HOST", "127.0.0.1")
MILVUS_PORT = int(os.getenv("MILVUS_PORT", "19530"))

然后安装依赖,启动

$ cd bootcamp/solutions/reverse_image_search/one_step/server
$ pip install -r requirements.txt
$ python main.py

在这里插入图片描述

启动前端

注意:

  • 前端demo只是一个功能演示,可以自己使用postman调用后端接口测试
  • 确保自己有nodejs环境

前端目录:cd bootcamp/solutions/reverse_image_search/one_step/client
1、首先修改/src/utils/Endpoints.ts中后端调用服务器端口,就是刚刚启动python项目端口
在这里插入图片描述

2、启动,我这边用的yarn

yarn install
yarn  start

在这里插入图片描述
浏览器输入http://localhost:3000/
在这里插入图片描述
填入需要训练入库的图片文件夹,点击+
在这里插入图片描述
我们其实可以f12查看其接口的调用,刚刚的训练数据已经入库,现在显示有14个特征
在这里插入图片描述

查询数据

在这里插入图片描述

### 设计与实现基于Milvus以图搜图系统 #### 1. 系统架构概述 构建一个高效稳定的以图搜图系统涉及多个技术栈的选择和集成。核心组件包括前端图片上传界面、后端服务器逻辑以及作为底层支撑的向量相似度搜索引擎——Milvus[^1]。 #### 2. 数据预处理阶段 为了使图像能够被有效地索引并用于后续查询,在接收到来自用户的输入图片之后,需先经过一系列预处理操作: - **特征提取**:利用预先训练好的卷积神经网络(CNN),比如ResNet50模型来抽取每张图片的关键特征点,并将其转换成固定长度的浮点数数组表示形式。 ```python from torchvision import models, transforms import torch def extract_features(image_path): model = models.resnet50(pretrained=True) preprocess = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ]) img_tensor = preprocess(Image.open(image_path)) batch_t = torch.unsqueeze(img_tensor, 0) with torch.no_grad(): output = model(batch_t) return output.numpy().flatten() ``` 此过程会生成一组描述该图片视觉特性的数值列表,即所谓的“嵌入”。 #### 3. 构建索引库 一旦获得了所有待检索对象对应的嵌入向量,则可借助于Milvus创建相应的集合(collection),并将这些向量批量导入其中建立索引。这一步骤对于提高实际运行效率至关重要,因为良好的索引结构有助于显著减少匹配时间复杂度。 ```python from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection connections.connect() fields = [ FieldSchema(name="id", dtype=DataType.INT64, is_primary=True), FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=2048), # 假设使用 ResNet50 提取的特征维度为 2048 ] schema = CollectionSchema(fields, "Image Search Index") collection_name = 'image_search_index' if not Collection.has_collection(collection_name): collection = Collection(name=collection_name, schema=schema) else: collection = Collection(name=collection_name) # 插入数据... data_to_insert = [[i for i in range(len(embeddings))], embeddings] mr = collection.insert(data_to_insert) print(f"Number of entities inserted: {mr.insert_count}") ``` 上述代码片段展示了如何定义字段模式、初始化Collection实例并向其内部添加记录条目。 #### 4. 实现搜索功能 当用户提交一张新照片请求查找最接近的结果集时,程序应当重复执行相同的特征提取流程得到目标向量;随后调用`search()`方法传入参数指定要比较的对象范围及其数量限制等条件信息完成最终定位工作。 ```python results = collection.search( data=query_vector, anns_field='embedding', param={"metric_type": "L2", "params": {"nprobe": 10}}, limit=top_k_matches, expr=None ) for result in results: print(f"ID={result.id}, Distance={result.distance}") ``` 这里采用欧氏距离(L2 norm)衡量两者的差异程度,并返回前K个最佳候选者供展示给访客查看。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值