以图搜图服务快速搭建
以图搜图服务快速搭建
电商公司,管理的商品少则几千,多则上百万。如何帮助用户从多如牛毛的商品中找到类似的商品就成了问题。
以图搜图就可以很好的帮助解决这个问题,通过 Towhee(resnet50 模型) + Milvus 如何实现本地环境搭建以图搜图。
Towhee 负责解析图片的特征向量,Milvus 负责存储特征向量然后进行向量查询。
Milvus Bootcamp 提供了很多解决方案 ,https://milvus.io/bootcamp/
其中就包含以图搜图的解决方案,根据图片相视度解决方案demo,这里实现了比较时候适合公司前后的分离环境的开箱即用的api实现。
配合前端大致效果如下:
包含如下接口
API接口
1.创建数据库
不同数据库对应不同的图片数据集合
Request
- Method: POST
- URL:
/milvus/img/table?table={tablename}
- 创建test数据集:
/milvus/img/table?table=test
- 创建test数据集:
- Headers:
Response
- Body
{"code": 10000,"message": "Successfully","data": null
}
2.新增图片
新增图片支持 base64 和url新增
Request
- Method: POST
- URL:
/milvus/img/add
- test 数据集新增图片数据:
/milvus/img/add
- test 数据集新增图片数据:
- Headers: Content-Type:application/json
- Body:
{"tags": "风景|标签","table": "test","brief":"{\"title\":\"hello world\"} 这里存一些属性","image": "base64(和url二选一,image优先级更高) ","url":"http:///xxx.jpp"
}
Response
- Body
{"code": 10000,"message": "Successfully","data": "8 返回数据id"
}
3.更新图片
更新图片支持 base64 和url,根据id进行更新
Request
- Method: POST
- URL:
/milvus/img/update
- Headers: Content-Type:application/json
- Body:
{"id":"1 必填","tags": "风景|标签","table": "test","brief":"{\"title\":\"hello world\"} 这里存一些属性","image": "base64(和url二选一,image优先级更高) ","url":"http:///xxx.jpp"
}
Response
- Body
{"code": 10000,"message": "Successfully","data": "8 返回数据id"
}
4.以图搜图
根据图片搜索相似图片
Request
- Method: POST
- URL:
/milvus/img/search
- Headers: Content-Type:application/json
- Body:
{"TOP_K": "2 查询多少个相似图","table": "test","url": "https://img.kakaclo.com/image%2FFSZW09057%2FFSZW09057_R_S_NUB%2F336bd601dfec33925ba1c581908b6c1e.jpg","image": "base64(和url二选一,image优先级更高) ",
}
Response
- Body
{"code": 10000,"message": "Successfully","data": [{"id": 513552,"tags": "","brief": "","distance": 0.00015275638725142926},{"id": 93,"tags": "","brief": "","distance": 0.0001584545971127227}]
}
distance 越小相似度越高。
5.删除图片
根据id删除
Request
- Method: POST
- URL:
/milvus/img/delete?id={id}&table={table}
- 删除test表id为6的数据
/milvus/img/delete?id=6&table=test
- 删除test表id为6的数据
- Headers:
- Body:
Response
- Body
{"code": 10000,"message": "Successfully"
}
6.删除整个数据集
删除milvus的和mysql的表,这个接口慎用,mysql和milvus数据会全部清除。
Request
- Method: POST
- URL:
/milvus/img/drop?table={table}
- 删除test数据集:
/milvus/img/drop?table=test
- 删除test数据集:
- Headers:
- Body:
Response
- Body
{"code": 10000,"message": "Successfully"
}
7.重新加载已经解析出特征的数据到milvus
这个在milvus升级、迁移和milvus数据损坏的情况下使用
可以将数据集对应的mysql表upload_status更新为0进行重新入milvus。
Request
- Method: POST
- URL:
/milvus/img/load?table={table}
- 将test mysql笔中upload_status为0的数据重新加载到milvus中:
/milvus/img/load??table=test
- 将test mysql笔中upload_status为0的数据重新加载到milvus中:
- Headers:
- Body:
Response
- Body
{"code": 10000,"message": "Successfully"
}
快速实践
环境安装
首先我们先有如下环境 python3,mysql,Milvus
python3,mysql就不多说了
Milvus 参考 https://milvus.io/docs/v2.1.x/install_standalone-docker.md
源码
https://github.com/AndsGo/reverse_image_search
配置
找到config.py
替换对应的 MILVUS 配置T 和 MYSQL配置
import os############### Milvus Configuration ###############
MILVUS_HOST = os.getenv("MILVUS_HOST", "127.0.0.1")
MILVUS_PORT = int(os.getenv("MILVUS_PORT", "19530"))
VECTOR_DIMENSION = int(os.getenv("VECTOR_DIMENSION", "2048"))
INDEX_FILE_SIZE = int(os.getenv("INDEX_FILE_SIZE", "1024"))
METRIC_TYPE = os.getenv("METRIC_TYPE", "L2")
DEFAULT_TABLE = os.getenv("DEFAULT_TABLE", "milvus_img_search")
TOP_K = int(os.getenv("TOP_K", "10"))############### MySQL Configuration ###############
MYSQL_HOST = os.getenv("MYSQL_HOST", "127.0.0.1")
MYSQL_PORT = int(os.getenv("MYSQL_PORT", "3306"))
MYSQL_USER = os.getenv("MYSQL_USER", "root")
MYSQL_PWD = os.getenv("MYSQL_PWD", "123456")
MYSQL_DB = os.getenv("MYSQL_DB", "milvus")
ERP_MYSQL_TABLE = os.getenv("ERP_MYSQL_TABLE", "milvus_img_search")############### Data Path ###############
UPLOAD_PATH = os.getenv("UPLOAD_PATH", "tmp/search-images")DATE_FORMAT = os.getenv("DATE_FORMAT", "%Y-%m-%d %H:%M:%S")############### Number of log files ###############
LOGS_NUM = int(os.getenv("logs_num", "0"))
数据库表结构 ,表是自动生成的
CREATE TABLE `test` (`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',`milvus_id` bigint(20) DEFAULT NULL COMMENT 'milvus 数据id',`tags` varchar(32) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '标识',`brief` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '图片摘要',`upload_status` tinyint(2) DEFAULT '0' COMMENT '0 待上传到milvus 1成功上传到milvus',`feature` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin COMMENT '图片特征向量',`create_date` datetime(3) DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',`modify_date` datetime(3) DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间',PRIMARY KEY (`id`),KEY `idx_tags` (`tags`) USING BTREE,KEY `idx_milvus_id` (`milvus_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='图片上传记录表';
启动
sh start_server.sh
Attu
https://milvus.io/docs/attu.md
Attu是 Milvus 的高效开源管理工具,提供了GUI显示
原文:
相关文章:

以图搜图服务快速搭建
以图搜图服务快速搭建 电商公司,管理的商品少则几千,多则上百万。如何帮助用户从多如牛毛的商品中找到类似的商品就成了问题。 以图搜图就可以很好的帮助解决这个问题,通过 Towhee(resnet50 模型) Milvus 如何实现本…...

【TensorFlow安装踩坑记录】
TensorFlow安装踩坑记录第一步,切换服务器cuda版本第二步,conda安装tensorflow记录一下最近安装Tensorflow v1时遇到的问题和解决办法第一步,切换服务器cuda版本 首先我想安装tensorflow 1.13.1,兼容的cuda版本是10.0,…...
03.03回溯法
class Solution { public:vector<int> temp;vector<vector<int>> ans;void dfs(int cur,int n,int k){//剪枝 temp 长度加上区间 [cur, n] 的长度小于 k,不可能构造出长度为 k 的 tempif(temp.size()(n-cur1)<k){return;}if(temp.size()k){ans…...

I.MX6ULL内核开发0:linux内核模块
目录 简要 一、内核模块的概念 二、内核模块加载、卸载过程 简要 1、内核模块的概念 2、内核模块的原理:内核模块在内核的加载、卸载过程。 一、内核模块的概念 内核,是一个操作系统的核心。是基于硬件的第一层软件扩充,提供操作系统的最…...

qsort快速排序的实现以及模拟实现qsort的功能(狠狠的拿捏)
当你为错过太阳而哭泣的时候,你也要再错过群星了。 --泰戈尔 目录 一.qsort快速排序的实现 二.模拟实现一个qsort功能的函数 一.qsort快速排序的实现 下面是 qsort() 函数的声明: void qsort(void *base, size_t nitems, size_t size, int (…...

[Java·算法·中等]LeetCode215. 数组中的第K个最大元素
每天一题,防止痴呆题目示例分析思路1题解1分析思路2题解2分析思路3题解3👉️ 力扣原文 题目 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不…...

xgboost:算法数学原理
xgboost算法数学原理 1、求预测值 y^iϕ(xi)∑k1Kfk(xi),fk∈F,(1)\hat{y}_i\phi\left(\mathbf{x}_i\right)\sum_{k1}^K f_k\left(\mathbf{x}_i\right), \quad f_k \in \mathcal{F},\tag{1} y^iϕ(xi)k1∑Kfk(xi),fk∈F,(1) F{f(x)wq(x)}(q:Rm→T,w∈RT)\mathca…...
map、multimap、unordered_map
引用:windows程序员面试指南 map map 红黑树 map 对value值无要求 map 有序,按照key值自动排序 map key值唯一 map 头文件:#include map 支持重载[]的运算符 map 为保持有序性,erase()开销大 multimap multimap 红黑树 multim…...
2023年全国最新会计专业技术资格精选真题及答案11
百分百题库提供会计专业技术资格考试试题、会计考试预测题、会计专业技术资格考试真题、会计证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 一、选择题 1.下列各项中,仅将生产过程中消耗的变动成本计入产品成本…...

Centos7搭建NFS
1.NFS简介Network File System(网络文件系统,通过网络让不同的机器系统之间可以彼此共享文件和目录,类似Samba服务。2.NFS挂载原理 在网络中服务器和客户端进行连接都是通过端口进行数据传输,而NFS服务端的端口是随机的,从而导致N…...

ThreadLoca基本使用以及与synchronized的区别
文章目录1. ThreadLocal介绍1.1 官方介绍1.2 基本使用1.2.1 常用方法1.2.2 使用案例1.3 ThreadLocal类与synchronized关键字1.3.1 synchronized同步方式1.3.2 ThreadLocal与synchronized的区别2. 运用场景_事务案例2.1 转账案例2.1.1 场景构建2.1.2 引入事务2.2 常规解决方案2.…...

【C++】纯虚函数、纯虚析构
纯虚函数语法:virtual 返回值类型 函数名(参数列表) 0纯虚函数的作用:不用定义!在多态中,通常父类中虚函数的实现是无意义的(因为主要用子类重写的,父类只是为了派生子类当做一个类族的顶层出现࿰…...
Python 进阶小技巧:7招展开嵌套列表
大家好,今天给大家讲解一个Python的进阶知识点:如何将一个嵌套的大列表展开形成一个列表。 小编提供了7种方法供大家学习参考: for循环 列表推导式 使用第三方库itertools 使用sum函数 python自加() 使用extend函…...

【Spring6】| Bean的作用域
目录 一:Bean的作用域 1. singleton(单例) 2. prototype(多例) 3. 其它scope 4. 自定义scop(了解) 一:Bean的作用域 1. singleton(单例) (1…...

Qt界面美化之自定义qss样式表
原生的QT界面不好看,有时候需要根据美工的设计图修改样式。如果使用QML的话搞界面是快,但是QML有点儿吃内存,有时简单的功能还是用传统c的widget方便些。好在有qss,传统界面也可以美化的。QSS称为Qt Style Sheets也就是Qt样式表&a…...

春招进行时:“211文科硕士吐槽工资5500” HR:行情和能力决定价值
学历重要,还是能力重要? 春招进行时,不少学生求职遇冷,会把原因归结为学历水平不够高、毕业院校不够档次、专业不够热门、非一线城市就业机会少等等。 直到上海一位211大学的文科男硕士,吐槽招聘会提供的岗位薪资待遇…...

【DaVinci Developer专题】-45-自动生成SWC中所有Runnable对应的C文件
点击返回「Autosar从入门到精通-实战篇」总目录 案例背景(共5页精讲): 在DaVinci Developer中,以Test_A_SWC的Runnable为例,见图0-1。我们现在尝试自动生成一个包含Test_A_SWC_Init和Test_A_SWC_Main函数原型(也是适用于 C/S Port Serve Runnable)的C文件。 图0-1 目…...
redis启动和关闭服务脚本
编译安装redis,自己写了个脚本。 简单实现启动、关闭和 查看redis服务。 基本流程如下: 脚本执行,必须附带1个参数,没有参数会提示附带参数。 脚本会获取redis-server进程数量。作为开启、关闭以及查看redis服务的数据依据。 …...
windows CMD快捷键:
🐱个人主页:莎萌玩家🙋♂️作者简介:全栈领域新星创作者、专注于全栈各领域技术,共同学习共同进步,一起加油呀!💫系列专栏:网络爬虫、WEB全栈开发📢资料领取…...

【C/C++语言】刷题|双指针|数组|单链表
主页:114514的代码大冒 qq:2188956112(欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ ) Gitee:庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 文章目录 目录 文章目录 前言 一、删除有序数组中的重复项 二、合并两个有序数组 三,移除…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...

GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态
前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...

【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章 摘要: 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言,受限于 C 语言本身的内存安全和并发安全问题,开发复杂模块极易引入难以…...