当前位置: 首页 > article >正文

milvus+flask山寨复刻《从零构建向量数据库》第7章

常规练手,图片搜索山寨版。拜读罗云大佬著作,结果只有操作层的东西可以上上手。

书中是自己写的向量数据库,这边直接用python拼个现成的milvus向量数据库。

1. 创建一个向量数据库以及对应的相应数据表:

# Milvus Setup Arguments
COLLECTION_NAME = 'animal_search'
DIMENSION = 2048
MILVUS_HOST = "localhost"
MILVUS_PORT = "19530"# Inference Arguments
BATCH_SIZE = 128from pymilvus import connections# Connect to the instance
connections.connect(host=MILVUS_HOST,port=MILVUS_PORT)from pymilvus import utility# Remove any previous collection with the same name
if utility.has_collection(COLLECTION_NAME):utility.drop_collection(COLLECTION_NAME)#创建保存ID、图片文件路径及Embeddings的Collection。
from pymilvus import FieldSchema, CollectionSchema, DataType, Collectionfields = [FieldSchema(name='id',dtype=DataType.INT64, is_primary=True, auto_id=True),FieldSchema(name='filepath', dtype=DataType.VARCHAR,max_length=200),FieldSchema(name='image_embedding',dtype=DataType.FLOAT_VECTOR,dim=DIMENSION)]
schema = CollectionSchema(fields=fields)
collection = Collection(name=COLLECTION_NAME, schema=schema)index_params = {'metric_type':'L2','index_type': "IVF_FLAT",'params':{'nlist':16384}
}
collection.create_index(field_name="image_embedding",index_params=index_params)
collection.load()

2. 写一堆图片进去存着,向量其实就是各种像素间的维度特征,

# Milvus Setup Arguments
COLLECTION_NAME = 'animal_search'
DIMENSION = 2048
MILVUS_HOST = "localhost"
MILVUS_PORT = "19530"# Inference Arguments
BATCH_SIZE = 128from pymilvus import connections# Connect to the instance
connections.connect(host=MILVUS_HOST, port=MILVUS_PORT)import globpaths = glob.glob('/mcm/vectorDB_training/animals_db/*',recursive=True)#分批预处理数据
import torch
# Load the embedding model with the last layer removed
model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet50', pretrained=True)
model = torch.nn.Sequential(*(list(model.children())[:-1]))
model.eval()from torchvision import transforms
# Preprocessing for images
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])
])#插入数据
from PIL import Image
from tqdm import tqdm# Embed function that embeds the batch and inserts it
def embed(data):from pymilvus import FieldSchema, CollectionSchema, DataType, Collectionfields = [FieldSchema(name='id',dtype=DataType.INT64, is_primary=True, auto_id=True),FieldSchema(name='filepath', dtype=DataType.VARCHAR,max_length=200),FieldSchema(name='image_embedding',dtype=DataType.FLOAT_VECTOR,dim=DIMENSION)]schema = CollectionSchema(fields=fields)collection = Collection(name=COLLECTION_NAME, schema=schema)with torch.no_grad():output = model(torch.stack(data[0])).squeeze()collection.insert([data[1],output.tolist()])collection.flush()data_batch = [[],[]]# Read the images into batches for embedding and insertion
for path in tqdm(paths):im = Image.open(path).convert('RGB')data_batch[0].append(preprocess(im))data_batch[1].append(path)if len(data_batch[0]) % BATCH_SIZE == 0:embed(data_batch)data_batch = [[],[]]# Embed and insert the remainder
if len(data_batch[0]) != 0:embed(data_batch)

3. 向量化图片的函数要单独拎出来,做搜索功能的时候用它。

import torch
import torchvision.transforms as transforms
from torchvision.models import resnet50
from PIL import Imagedef extract_features(image_path):# 加载预训练的 ResNet-50 模型model = resnet50(pretrained=True)model = torch.nn.Sequential(*list(model.children())[:-1])  #移除fc层,不移除,向量最后就是1000层,而不是2048model.eval()# 图像预处理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 = Image.open(image_path)img_t = preprocess(img)batch_t = torch.unsqueeze(img_t, 0)# 提取特征with torch.no_grad():out = model(batch_t)# 将特征向量转换为一维数组并返回return out.flatten().numpy()

4. 用flask做的界面

from flask import Flask,request,jsonify
from flask import render_template
from image_eb import extract_features
#from pymilvus import connections
from pymilvus import MilvusClientimport logging
import os
import shutilMILVUS_HOST = "localhost"
MILVUS_PORT = "19530"
COLLECTION_NAME = 'animal_search'
TOP_K = 3app = Flask(__name__)
milvus_client = MilvusClient(uri="http://localhost:19530")@app.route("/")
def index():return render_template("index.html")@app.route("/upload",methods=["POST"])
def upload_image():image_file = request.files["image"]image_id_str = request.form.get("image_id")data = []#检查image_id是否存在。if not image_id_str:return jsonify({"message": "Image ID is required"}),400#image id转化为整型try:image_id = int(image_id_str)data.append(image_id)except ValueError:return jsonify({"message": "Invalid image ID. It must be an integer"}),400filename = image_file.filenameimage_path = os.path.join("static/images",image_id_str)image_file.save(image_path)image_features = extract_features(image_path)data.append(image_features)data_dict = dict(filepath=image_path,image_embedding=data[1])#更新数据库中记录milvus_client.insert(collection_name=COLLECTION_NAME,data=[data_dict])return jsonify({"message": "Image uploaded successfully", "id": image_id})@app.route("/search",methods=["POST"])
def search_image():image_file = request.files["image"]image_path = os.path.join("static/images","temp_image.jpg")image_file.save(image_path)image_features = extract_features(image_path)data_li = [extract_features(image_path).tolist()]search_result = milvus_client.search(collection_name=COLLECTION_NAME,data=data_li,output_fields=["filepath"],limit=TOP_K,search_params={'metric_type': 'L2', 'params': {}},)dict_search_result = search_result[0]arr_search_result = []destination_folder = '/mcm/vectorDB_training/static/images'for index,value in enumerate(dict_search_result):source_file = value["entity"]["filepath"]base_file_name = os.path.basename(source_file)destination_file = os.path.join(destination_folder, base_file_name)shutil.copy(source_file, destination_file)key_file_name = os.path.join("/static/images",base_file_name)arr_search_result.append(key_file_name)        image_urls = [f"{filepath}" for filepath in arr_search_result]return jsonify({"image_urls":image_urls})if __name__=="__main__":app.run(host='0.0.0.0',port=5020,debug=True)

小网站结构,以及其他杂代码,可以查看以及直接下载:https://www.ituring.com.cn/book/3305

相关文章:

milvus+flask山寨复刻《从零构建向量数据库》第7章

常规练手,图片搜索山寨版。拜读罗云大佬著作,结果只有操作层的东西可以上上手。 书中是自己写的向量数据库,这边直接用python拼个现成的milvus向量数据库。 1. 创建一个向量数据库以及对应的相应数据表: # Milvus Setup Argume…...

Spring Cloud: Nacos

Nacos Nacos是阿里巴巴开源的一个服务发现,配置管理和服务管理平台。只要用于分布式系统中的微服务注册,发现和配置管理,nacos是一个注册中心的组件 官方仓库:https://nacos.io/ Nacos的下载 Releases alibaba/nacos 在官网中…...

AI生成视频推荐

以下是一些好用的 AI 生成视频工具: 国内工具 可灵 :支持文本生成视频、图片生成视频,适用于广告、电影剪辑和短视频制作,能在 30 秒内生成 6 秒的高清视频(1440p),目前处于免费测试阶段。 即…...

Win11安装APK方法详解

1、官方win11系统 预览版 开发版 正式版 都行 2、同时你还需要开启主板 BIOS 虚拟化选项(具体名称不同主板略有不同) 这一步自行百度 开始:先去确定有没有开启虚拟化 任务管理器检查—— 虚拟化是否已经开启,如果没有自己去BIO…...

SSH终端登录与网络共享

SSH 是较可靠,专为远程登录会话和其他网络服务提供安全性的协议 注意 SSH终端登录的前提是:电脑和板卡都能够通过网络相连接及通信 与连接互联网不一样,SSH可以不用互联网,只要电脑和板卡组成一个小型网络即可 网络方案 如果您…...

Android 13 默认打开 使用屏幕键盘

原生设置里,系统-语言和输入法-实体键盘-使用屏幕键盘 选项, 关闭时,外接物理键盘,如USB键盘,输入时不会弹出软键盘。 打开时,外接物理键盘,如USB键盘,输入时会弹出软键盘。 这个选…...

操作系统学习笔记第2章 (竟成)

第 2 章 进程管理 【考纲内容】 1.进程与线程: (1) 进程 / 线程的基本概念; (2) 进程 / 线程的状态与转换; (3) 线程的实现:内核支持的线程;线程库支持的线程; (4) 进程与线程的组织与控制; (5)…...

行业黑化.新平面

最近听了一句行业黑话:"这个功能是新平面吗?" 沙比了吧,什么是平面,还新的,旧的都不动是啥 再结合日常口语"管理面"、"控制面"、"数据面",问了问DeepSeek 解释还是…...

Veins同时打开SUMO和OMNeT++的GUI界面

进入 Veins 工程目录(即包含 sumo-launchd.py 的目录),打开终端设置 SUMO_HOME 环境变量(指向你安装的 SUMO 路径): export SUMO\_HOME/home/veins/src/sumo-1.11.0编译 Veins 工程(包含 OMNeT…...

复合机器人案例启示:富唯智能如何以模块化创新引领工业自动化新标杆

在国产工业机器人加速突围的浪潮中,富唯智能复合机器人案例凭借其高精度焊接与智能控制技术,成为行业标杆。然而,随着制造业对柔性化、全场景协作需求的升级,复合机器人正从单一功能向多模态协同进化。作为这一领域的创新者&#…...

Python爬虫实战:获取文学网站四大名著并保存到本地

一、引言 1.1 研究背景 中国古典四大名著承载着深厚的文化底蕴,是中华民族的宝贵精神财富。在互联网时代,网络文学资源虽丰富多样,但存在分散、质量参差不齐等问题 。部分文学网站存在访问限制、资源缺失等情况,用户难以便捷获取完整、高质量的经典著作内容。开发专业的爬…...

从需求到用例的AI路径:准确率与挑战

用工作流生成测试用例和自动化测试脚本! 引言:用例的黄金起点 在软件工程中,“测试用例”是连接需求理解与质量保障之间的关键桥梁。一份高质量的测试用例,不仅是验证功能实现是否符合需求的工具,更是产品风险感知、用…...

Linux在web下http加密和配置虚拟主机及动态页面发布

web服务器的数据加密 1.简介:由于http协议以明文方式发送,不提供任何方式的数据加密,也不适合传输一些重要的信息,如银行卡号、密码等,解决该缺陷设计了安全套接字层超文本传输协议https; 2.https的握手流…...

C++ learning day 02

目录 引言 编译定义: 查看obj文件 1. 禁用预处理 2. CTRL F7 编译math.cpp 3. 查看obj文件 4. 查看.asm文件(汇编程序) 引言 今天介绍C中,一个Cpp文件经过汇编后得到obj文件,以及obj文件的内容&a…...

使用fdisk 、gdisk管理分区

用 fdisk 管理分区 fdisk 命令工具默认将磁盘划分为 mbr 格式的分区 命令: fdisk 设备名 fdisk 命令以交互方式进行操作的,在菜单中选择相应功能键即可 [rootlocalhost ~]# fdisk /dev/sda # 对 sda 进行分区 Command (m for help): # 进入 fdis…...

如何通过C# 获取Excel单元格的数据类型

在处理 Excel 文件时,了解单元格的数据类型有助于我们正确地解析和处理数据。Free Spire.XLS 是一款功能强大且免费的.NET 组件,支持高效地操作 Excel 文件,包括读取单元格类型。本文将详细介绍如何使用 Free Spire.XLS 来获取 Excel 单元格的…...

Servlet、HttpServlet 和 DispatcherServlet 区别与关系

在 Java Web 开发中,Servlet、HttpServlet 和 DispatcherServlet 是非常常见的类。 一、Servlet 接口(javax.servlet.Servlet) ✅ 基本介绍: 所属包:javax.servlet.Servlet作用:是所有 Servlet 的根接口,定义了 Servlet 生命周期的基本方法。特点: 与协议无关(可以用…...

Fiori学习专题三十九:使用标准模板创建一个应用程序

之前的课程我们按照教程一步一步创建了我们的一个应用程序,但是总不能每次开发都像这样子来做,那样就太慢了。事实上MVC架构的应用程序,是有很多模板,今天我们就按照模板来创建一个应用程序。 开发工具还是使用vscode,…...

模型 启动效应

系列文章分享模型,了解更多👉 模型_思维模型目录。刺激先行激活,后续认知更顺畅。 1 启动效应的应用 1.1 求职面试中对面试官的影响 背景:一家知名公司在招聘过程中发现,面试官对候选人的评价往往受到多种因素的影响…...

Spring MVC常见注解详解

Spring MVC提供了丰富的注解,以简化Web应用开发过程。下面我将详细描述一些主要的注解、它们的作用、应用场景以及具体的应用示例。 1. Controller 作用: 标记一个类作为Spring MVC的控制器组件。这个注解是定义处理HTTP请求的入口点。 标识控制器组件: Controlle…...

【前端分享】CSS实现3种翻页效果类型,附源码!

使用 css 可以实现多种翻页效果&#xff0c;比如书本翻页、卡片翻转等。以下是两种常见的翻页效果实现&#xff1a; 效果 1&#xff1a;书本翻页效果 通过 transform 和 rotateY 实现 3D 翻页效果。 html 结构 <divclass"book"> <divclass"page pa…...

vue使用rules实现表单校验——校验用户名和密码

编写校验规则 常规校验 const rules {username: [{ required: true, message: 请输入用户名, trigger: blur },{ min: 5, max: 16, message: 长度在 5 到 16 个字符, trigger: blur }],password: [{ required: true, message: 请输入密码, trigger: blur },{ min: 5, max: 1…...

中国古代史2

夏朝&#xff08;公元前2070-公元前1600年&#xff09; 1.禹建立了我国历史上第一个奴隶制国家–夏朝&#xff0c;定都阳城。禹传启&#xff0c;世袭制代替禅让制。 2.夏代都城&#xff1a;二里头遗址位于今河南洛阳偃师二里头村。发现了大型绿松石龙形器&#xff0c;被命名为…...

Linux云计算训练营笔记day05(Rocky Linux中的命令:管道操作 |、wc、find、vim)

管道操作 | 作用: 将前面命令的输出&#xff0c;传递给后面命令&#xff0c;作为后面命令的参数 head -3 /etc/passwd | tail -1 取第三行 head -8 /etc/passwd | tail -3 | cat -n 取6 7 8行 ifconfig | head -2 | tail -1 只查看IP地址 ifconfig | grep 192 过滤192的ip…...

diy装机成功录

三天前&#xff0c;我正式开启了这次装机之旅&#xff0c;购入了一颗性能强劲的 i5-12400 CPU&#xff0c;一块绘图能力出色的 3060ti 显卡&#xff0c;还有技嘉主板、高效散热器、16G 内存条、2T 固态硬盘&#xff0c;以及气派的机箱和风扇&#xff0c;满心期待能亲手打造一台…...

Flink 实时数据一致性与 Exactly-Once 语义保障实战

在构建企业级实时数仓的过程中,“数据一致性” 是保障指标准确性的核心能力,尤其是在金融、电商、医疗等对数据敏感度极高的场景中。Flink 作为流批一体的实时计算引擎,其内建的 Exactly-Once 语义为我们提供了强有力的保障机制。本篇将围绕如何实现端到端的数据一致性、如何…...

两个数组的交集(暴力、set、哈希)

一.题目 给定两个数组 nums1 和 nums2 &#xff0c;返回 它们的 交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 示例 1&#xff1a; 输入&#xff1a;nums1 [1,2,2,1], nums2 [2,2] 输出&#xff1a;[2]示例 2&#xff1a; 输入&#xf…...

【 Redis | 实战篇 缓存 】

目录 前言&#xff1a; 1.认识缓存 2.添加Redis缓存 2.1.根据id查询商铺缓存 2.2.优化根据id查询商铺缓存 3.缓存更新策略 3.1.三种策略 3.2.策略选择 3.3.主动更新的方案 3.4. Cache Aside的模式选择 3.5.最佳实践方案 4.缓存三大问题 4.1.缓存穿透 4.1.1.介绍 …...

2025年全新 GPT 4.5 AI 大模型 国内免费调用

一、中转账号注册 第一步&#xff1a;打开宙流AI中转站&#xff0c;网站地址如下&#xff1a; 宙流AI中转站 按照上图中的操作步骤&#xff0c;通过邮箱进行账号注册&#xff0c;注册完毕后&#xff0c;网站初始会分配0.4刀的免费额度&#xff0c;获取额度后&#xff0c;即可…...

“睿思 BI” 系统介绍

“睿思 BI” 商业智能系统是由成都睿思商智科技有限公司自主研发的企业数据分析系统&#xff0c;以下是对该系统的详细介绍&#xff1a; 功能模块 &#xff1a; • 数据集成与准备 &#xff1a;支持数据导入、数据填报、数据 ETL 等功能&#xff0c;可抽取企业在经营过程中产生…...