使用开源PolarDB和imgsmlr进行高效的图片存储和相似度搜索

PolarDB的云原生架构提供高性价比的数据存储、可扩展的灵活性、高效的并行计算能力以及快速的数据搜索和处理能力。PolarDB通过结合计算算法,挖掘业务数据的价值,将其转化为生产力。

本文介绍如何使用开源PolarDB和imgsmlr存储图像特征值,并快速进行图像相似度搜索。

本演示的测试环境为 macOS + Docker。关于部署PolarDB的详细说明,请参考以下文章:

PolarDB的简单部署

原则

有多种方法可以对图像进行数字化,例如将其划分为正方形,并用原色和灰度表示每个正方形。然后将图像逐层逐渐缩小(例如,从 81 个正方形缩小到 9 个正方形)并压缩成一个较小的正方形,形成另一个正方形阵列。N^2N^2

在图像相似性搜索过程中,将比较两个方形数组之间的向量距离。N^2

通过使用GIST索引接口,可以实现向量相似性搜索的快速收敛。这涉及使用中心点作为存储桶的数据分区,并采用多层缩略图压缩搜索算法(请参阅本文的后面部分)。

本文介绍如何使用开源的PolarDB和imgsmlr来存储图像特征值,并高效进行图像相似度搜索。

1. 介绍两种数据类型:细节向量和特征向量。特征向量占用的空间更小,查询效率更高,通常用于初始数据过滤,而细节向量则用于更细致的过滤。

数据类型存储长度描述
模式16388 字节Haar小波变换在图像上的结果
签名64 字节使用 GiST 索引进行快速搜索的模式的简短表示

2、介绍几种图像转换功能接口。

功能返回类型描述
jpeg2pattern(bytea)模式将jpeg图像转换为图案
png2pattern(bytea)模式把png图像转换为图案
GIF2模式(bytea)模式将gif图像转换为图案
pattern2signature(模式)签名从模式创建签名
shuffle_pattern(模式)模式随机播放模式,降低对图像偏移的敏感度

3. 引入两种向量距离计算算子和索引排序支持。

算子左型正确类型返回类型描述
<->模式模式浮点8两种模式之间的欧克里得距离
<->签名签名浮点8两个特征之间的欧克里底距离

在PolarDB上部署imgsmlr

1. 安装 png 和 jpeg 的图片库依赖。

sudo yum install -y libpng-devel  
sudo yum install -y libjpeg-turbo-devel  sudo vi /etc/ld.so.conf  
# add  
/usr/lib64  sudo ldconfig  

2. 安装gd库,用于jpeg、png、gif等图片格式的序列化转换。

git clone --depth 1 https://github.com/libgd/libgd  cd libgd/  mkdir build  cd build  cmake -DENABLE_PNG=1 -DENABLE_JPEG=1 ..  make  sudo make install  ...  
-- Installing: /usr/local/lib64/libgd.so.3.0.16  
-- Installing: /usr/local/lib64/libgd.so.3  
...  sudo vi /etc/ld.so.conf  
# add  
/usr/local/lib64  sudo ldconfig  export LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH  

3. 安装 imgsmlr。

git clone --depth 1 https://github.com/postgrespro/imgsmlr  cd imgsmlr/  
USE_PGXS=1 make  USE_PGXS=1 make install  
ldd /home/postgres/tmp_basedir_polardb_pg_1100_bld/lib/imgsmlr.so  linux-vdso.so.1 =>  (0x00007ffc25d52000)  libgd.so.3 => /usr/local/lib64/libgd.so.3 (0x00007fd7a4463000)  libc.so.6 => /lib64/libc.so.6 (0x00007fd7a3ee5000)  libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fd7a3bdd000)  libm.so.6 => /lib64/libm.so.6 (0x00007fd7a38db000)  libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fd7a36c5000)  /lib64/ld-linux-x86-64.so.2 (0x00007fd7a42b3000)  

4. 加载插件。

psql  create extension imgsmlr ;  

场景模拟和架构设计实践

生成测试图像。

cd imgsmlr  
USE_PGXS=1 make installcheck  

图像导入、矢量化和图像相似性搜索测试。

psql-- Create a plug-in.
CREATE EXTENSION imgsmlr;  -- Create a table that stores the binary of the original image.
CREATE TABLE image (id integer PRIMARY KEY, data bytea);  -- Create a temporary table for import.
CREATE TABLE tmp (data text);  -- Import images.
\copy tmp from 'data/1.jpg.hex'  
INSERT INTO image VALUES (1, (SELECT decode(string_agg(data, ''), 'hex') FROM tmp));  
TRUNCATE tmp;  
\copy tmp from 'data/2.png.hex'  
INSERT INTO image VALUES (2, (SELECT decode(string_agg(data, ''), 'hex') FROM tmp));  
TRUNCATE tmp;  
\copy tmp from 'data/3.gif.hex'  
INSERT INTO image VALUES (3, (SELECT decode(string_agg(data, ''), 'hex') FROM tmp));  
TRUNCATE tmp;  
\copy tmp from 'data/4.jpg.hex'  
INSERT INTO image VALUES (4, (SELECT decode(string_agg(data, ''), 'hex') FROM tmp));  
TRUNCATE tmp;  
\copy tmp from 'data/5.png.hex'  
INSERT INTO image VALUES (5, (SELECT decode(string_agg(data, ''), 'hex') FROM tmp));  
TRUNCATE tmp;  
\copy tmp from 'data/6.gif.hex'  
INSERT INTO image VALUES (6, (SELECT decode(string_agg(data, ''), 'hex') FROM tmp));  
TRUNCATE tmp;  
\copy tmp from 'data/7.jpg.hex'  
INSERT INTO image VALUES (7, (SELECT decode(string_agg(data, ''), 'hex') FROM tmp));  
TRUNCATE tmp;  
\copy tmp from 'data/8.png.hex'  
INSERT INTO image VALUES (8, (SELECT decode(string_agg(data, ''), 'hex') FROM tmp));  
TRUNCATE tmp;  
\copy tmp from 'data/9.gif.hex'  
INSERT INTO image VALUES (9, (SELECT decode(string_agg(data, ''), 'hex') FROM tmp));  
TRUNCATE tmp;  
\copy tmp from 'data/10.jpg.hex'  
INSERT INTO image VALUES (10, (SELECT decode(string_agg(data, ''), 'hex') FROM tmp));  
TRUNCATE tmp;  
\copy tmp from 'data/11.png.hex'  
INSERT INTO image VALUES (11, (SELECT decode(string_agg(data, ''), 'hex') FROM tmp));  
TRUNCATE tmp;  
\copy tmp from 'data/12.gif.hex'  
INSERT INTO image VALUES (12, (SELECT decode(string_agg(data, ''), 'hex') FROM tmp));  
TRUNCATE tmp;  -- Convert the original image into an image feature vector and an image signature, and import it into a new table.CREATE TABLE pat AS (  SELECT  id,  shuffle_pattern(pattern)::text::pattern AS pattern,  pattern2signature(pattern)::text::signature AS signature  FROM (  SELECT   id,  (CASE WHEN id % 3 = 1 THEN jpeg2pattern(data)  WHEN id % 3 = 2 THEN png2pattern(data)  WHEN id % 3 = 0 THEN gif2pattern(data)  ELSE NULL END) AS pattern   FROM   image  ) x   
);  -- Add a PK.
ALTER TABLE pat ADD PRIMARY KEY (id);  -- Create an index in the image signature field.
ALTER TABLE pat ADD PRIMARY KEY (id);  -- Self-correlate and query image similarity (Euclidean distance).
SELECT p1.id, p2.id, round((p1.pattern <-> p2.pattern)::numeric, 4) FROM pat p1, pat p2 ORDER BY p1.id, p2.id;  
SELECT p1.id, p2.id, round((p1.signature <-> p2.signature)::numeric, 4) FROM pat p1, pat p2 ORDER BY p1.id, p2.id;  -- Use the index to quickly search for similar images.
SET enable_seqscan = OFF;  SELECT id FROM pat ORDER BY signature <-> (SELECT signature FROM pat WHERE id = 1) LIMIT 3;  
SELECT id FROM pat ORDER BY signature <-> (SELECT signature FROM pat WHERE id = 4) LIMIT 3;  
SELECT id FROM pat ORDER BY signature <-> (SELECT signature FROM pat WHERE id = 7) LIMIT 3;  
SELECT id FROM pat ORDER BY signature <-> (SELECT signature FROM pat WHERE id = 10) LIMIT 3;  

结果:

SELECT p1.id, p2.id, round((p1.signature <-> p2.signature)::numeric, 4) FROM pat p1, pat p2 ORDER BY p1.id, p2.id;  id | id | round    
----+----+--------  1 |  1 | 0.0000  1 |  2 | 0.5914  1 |  3 | 0.6352  1 |  4 | 1.1431  1 |  5 | 1.3843  1 |  6 | 1.5245  1 |  7 | 3.1489  1 |  8 | 3.4192  1 |  9 | 3.4571  1 | 10 | 4.0683  1 | 11 | 3.3551  1 | 12 | 2.4814  2 |  1 | 0.5914  2 |  2 | 0.0000  2 |  3 | 0.7785  2 |  4 | 1.1414  2 |  5 | 1.2839  2 |  6 | 1.4373  2 |  7 | 3.2969  2 |  8 | 3.5381  2 |  9 | 3.5788  2 | 10 | 4.4256  2 | 11 | 3.6138  2 | 12 | 2.7975  3 |  1 | 0.6352  3 |  2 | 0.7785  3 |  3 | 0.0000  3 |  4 | 1.0552  3 |  5 | 1.3885  3 |  6 | 1.4925  3 |  7 | 3.0224  3 |  8 | 3.2555  3 |  9 | 3.2907  3 | 10 | 4.0521  3 | 11 | 3.2095  3 | 12 | 2.4304  4 |  1 | 1.1431  4 |  2 | 1.1414  4 |  3 | 1.0552  4 |  4 | 0.0000  4 |  5 | 0.5904  4 |  6 | 0.7594  4 |  7 | 2.6952  4 |  8 | 2.9019  4 |  9 | 2.9407  4 | 10 | 3.8655  4 | 11 | 2.9710  4 | 12 | 2.1766  5 |  1 | 1.3843  5 |  2 | 1.2839  5 |  3 | 1.3885  5 |  4 | 0.5904  5 |  5 | 0.0000  5 |  6 | 0.7044  5 |  7 | 2.9206  5 |  8 | 3.1147  5 |  9 | 3.1550  5 | 10 | 4.0454  5 | 11 | 3.2023  5 | 12 | 2.3612  6 |  1 | 1.5245  6 |  2 | 1.4373  6 |  3 | 1.4925  6 |  4 | 0.7594  6 |  5 | 0.7044  6 |  6 | 0.0000  6 |  7 | 2.8572  6 |  8 | 3.0659  6 |  9 | 3.1054  6 | 10 | 3.7803  6 | 11 | 2.7595  6 | 12 | 2.0282  7 |  1 | 3.1489  7 |  2 | 3.2969  7 |  3 | 3.0224  7 |  4 | 2.6952  7 |  5 | 2.9206  7 |  6 | 2.8572  7 |  7 | 0.0000  7 |  8 | 0.6908  7 |  9 | 0.7082  7 | 10 | 4.3939  7 | 11 | 3.5039  7 | 12 | 3.2914  8 |  1 | 3.4192  8 |  2 | 3.5381  8 |  3 | 3.2555  8 |  4 | 2.9019  8 |  5 | 3.1147  8 |  6 | 3.0659  8 |  7 | 0.6908  8 |  8 | 0.0000  8 |  9 | 0.0481  8 | 10 | 4.6824  8 | 11 | 3.7398  8 | 12 | 3.5689  9 |  1 | 3.4571  9 |  2 | 3.5788  9 |  3 | 3.2907  9 |  4 | 2.9407  9 |  5 | 3.1550  9 |  6 | 3.1054  9 |  7 | 0.7082  9 |  8 | 0.0481  9 |  9 | 0.0000  9 | 10 | 4.6921  9 | 11 | 3.7523  9 | 12 | 3.5913  10 |  1 | 4.0683  10 |  2 | 4.4256  10 |  3 | 4.0521  10 |  4 | 3.8655  10 |  5 | 4.0454  10 |  6 | 3.7803  10 |  7 | 4.3939  10 |  8 | 4.6824  10 |  9 | 4.6921  10 | 10 | 0.0000  10 | 11 | 1.8252  10 | 12 | 2.0838  11 |  1 | 3.3551  11 |  2 | 3.6138  11 |  3 | 3.2095  11 |  4 | 2.9710  11 |  5 | 3.2023  11 |  6 | 2.7595  11 |  7 | 3.5039  11 |  8 | 3.7398  11 |  9 | 3.7523  11 | 10 | 1.8252  11 | 11 | 0.0000  11 | 12 | 1.2933  12 |  1 | 2.4814  12 |  2 | 2.7975  12 |  3 | 2.4304  12 |  4 | 2.1766  12 |  5 | 2.3612  12 |  6 | 2.0282  12 |  7 | 3.2914  12 |  8 | 3.5689  12 |  9 | 3.5913  12 | 10 | 2.0838  12 | 11 | 1.2933  12 | 12 | 0.0000  
(144 rows)  postgres=# SELECT id FROM pat ORDER BY signature <-> (SELECT signature FROM pat WHERE id = 1) LIMIT 3;  id   
----  1  2  3  
(3 rows)  postgres=# SELECT id FROM pat ORDER BY signature <-> (SELECT signature FROM pat WHERE id = 4) LIMIT 3;  id   
----  4  5  6  
(3 rows)  postgres=# SELECT id FROM pat ORDER BY signature <-> (SELECT signature FROM pat WHERE id = 7) LIMIT 3;  id   
----  7  8  9  
(3 rows)  postgres=# SELECT id FROM pat ORDER BY signature <-> (SELECT signature FROM pat WHERE id = 10) LIMIT 3;  id   
----  10  11  12  
(3 rows)  
postgres=# explain SELECT id FROM pat ORDER BY signature <-> (SELECT signature FROM pat WHERE id = 10) LIMIT 3;QUERY PLAN                                     
------------------------------------------------------------------------------------Limit  (cost=8.29..10.34 rows=3 width=8)InitPlan 1 (returns $0)->  Index Scan using pat_pkey on pat pat_1  (cost=0.14..8.15 rows=1 width=64)Index Cond: (id = 10)->  Index Scan using pat_signature_idx on pat  (cost=0.13..8.37 rows=12 width=8)Order By: (signature <-> $0)
(6 rows)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/186672.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis的强大特性--动态SQL

目录 前言 if trim where set foreach 前言 动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架&#xff0c;你应该能理解根据不同条件拼接 SQL 语句有多痛苦&#xff0c;例如拼接时要确保不能忘记添加必要的空格&#xff0c;还要注意去掉列表…

【java】记一次Java应用查询不到最新数据的问题

文章目录 项目第一次上线前&#xff0c;生产环境调试阶段&#xff0c;项目经理反馈在备机房所在环境验证时报错&#xff1a;id不存在。 我赶紧去排查&#xff0c;查看日志&#xff0c;发现日志里打印的id是旧数据记作A&#xff0c;拿着这个数据去调其他系统提示id不存在。 查看…

JC/T 2087-2011建筑装饰用仿自然面艺术石检测

建筑装饰用仿自然面艺术石是指以硅酸盐水泥、轻质骨料为主要原料经浇筑成型的饰面装饰材料。 JC/T 2087-2011建筑装饰用仿自然面艺术石测试&#xff1a; 测试项目 测试方法 外观质量 GB/T 18601 尺寸偏差 GB/T 18601 体积密度 GB/T 9966.3 吸水率 GB/T 9966.3 压缩强…

File类

File 概述 File: 路径 IO流: 传输 路径 相对路径, 绝对路径 File File对象就表示一个路径&#xff0c;可以是文件的路径、也可以是文件夹的路径这个路径可以是存在的&#xff0c;也允许是不存在的 构造方法 代码示例: package FileTest1;import java.io.File;public c…

1+X网络系统建设与运维练习题

1.OSPF的最优路由&#xff0c;会放到IP路由表中指导数据转发 &#xff08;x&#xff09; 2.当AP工作在2.4GHz频段的时候&#xff0c;AP工作的频率范围是2.4GHz~2.4835GHZ。在此频率范围内又划分出14个信道。每信道的中心频率相隔5MHz&#xff0c;每个信道可供占用的带宽为22MHz…

虚幻学习笔记1—给UI添加动画

一、前言 本文所使用的虚幻版本为5.3.2&#xff0c;之前工作都是用unity&#xff0c;做这类效果用的最多的是一个DoTween的插件&#xff0c;在虚幻中都内置集成了这这种效果制作。 图1.1 UI动画 二、过程 1、首先&#xff0c;在诸如按钮、图像等可交互控件中选中&#xff0c;如…

R语言单因素方差分析+差异显著字母法标注+逐行详细解释

R语言单因素方差分析 代码如下 df <- read.csv("data.csv",header TRUE,row.names 1) library(reshape2) df <- melt(df,idc()) names(df) <- c(trt, val) df aov1 <- aov(val~trt,datadf) summary(aov1)library(agricolae) data <- LSD.test(aov…

5 存储器映射和寄存器

文章目录 5.3 芯片内核5.3.1 ICache5.3.2 DCache5.3.3 FlexRAM 5.4 存储器映射5.4.1 存储器功能划分5.4.1.1 存储器 Block0 内部区域功能划分5.4.1.2 储存器 Block1 内部区域功能划分5.4.1.3 储存器 Block2 内部区域功能划分 5.5 寄存器映射5.5.1 GPIO1的输出数据寄存器 5.3 芯…

客户案例:EDLP助力金融行业打造高效数据防泄露体系

客户背景 某金融机构是一家以金融科技为核心&#xff0c;致力于为客户提供全方位、智能化、便捷化金融服务的综合性企业。公司总部位于南京&#xff0c;业务范围覆盖全国&#xff0c;拥有强大的技术研发团队和优秀的业务精英&#xff0c;为客户提供全方位的金融服务解决方案。 …

Qt-No relevant classes found. No output generated问题解决

qt在编译时会使用moc&#xff0c;即Meta-Object Compiler&#xff0c;对任何继承于QObject的子类我们都应在类开头写上Q_OBJECT&#xff0c;而moc做的一件事情便是将带有Q_OBJECT的类的cpp文件使用moc进行处理&#xff0c;这是因为Q_OBJECT实际上声明了一些函数&#xff0c;而m…

子类出现和父类同名的成员,子类如何访问父类的同名成员?

一. 子类访问子类同名的成员&#xff0c;直接访问即可。 #include <iostream> using namespace std;class Base { public:Base(int age 0) : m_age(age) {}int get_age() {return m_age;}static int get_counter() {return ms_counter;}int m_age;static int ms_counte…

融资经理简历模板

这份简历内容&#xff0c;以综合柜员招聘需求为背景&#xff0c;我们制作了1份全面、专业且具有参考价值的简历案例&#xff0c;大家可以灵活借鉴。 融资经理简历在线编辑下载&#xff1a;百度幻主简历 求职意向 求职类型&#xff1a;全职 意向岗位&#xff1a;融资经理 …

什么是网络攻击?阿里云服务器可以避免被攻击吗?

网络攻击是指:损害网络系统安全属性的任何类型的进攻动作。进攻行为导致网络系统的机密性、完整性、可控性、真实性、抗抵赖性等受到不同程度的破坏。 网络攻击有很多种&#xff0c;网络上常见的攻击有DDOS攻击、CC攻击、SYN攻击、ARP攻击以及木马、病毒等等&#xff0c;所以再…

xxl-job适配postgresql数据库

xxl-job支持了mysql数据库&#xff0c;其他的数据库适配得自己弄一下&#xff0c;下面以目前最新的2.4.1为例进行说明适配postgresql数据库的过程。 获取源代码 从github或gitee获取源代码&#xff0c;目前最新版本2.4.1 xxl官网&#xff1a;分布式任务调度平台XXL-JOB 建立…

开闭原则:提高扩展性的小技巧

什么是开闭原则 开闭原则的英文全称是 Open Closed Principle&#xff0c;简写为 OCP。它的英文描述是: software entities (modules, classes, functions, etc.) should be open for extension , but closed for modification。我们把它翻译成中文就是:软件实体(模块、类、方…

Linux安装Java环境

处理安装环境 检查系统版本 [rootjeven ~]# cat /etc/centos-release CentOS Linux release 7.6.1810 (Core)检查系统内核版本 [rootjeven ~]# uname -r 6.1.8-1.el7.elrepo.x86_64清空卸载java环境&#xff08;如果已经安装了&#xff09; 查询java所在位置 [rootjeven …

node =》 path 模块的常用API

目录 简介 API path.join([...paths])&#xff1a;将所有给定的路径片段连接在一起&#xff0c;并规范化生成的路径。 path.resolve([...paths])&#xff1a;将路径或路径片段的序列解析为绝对路径。 path.basename(path[, ext])&#xff1a;返回路径的最后一部分&#xf…

什么是Anaconda?作用是?使用python必须要安装嘛?

一、什么是Anaconda以及其作用&#xff1f; 通俗来讲&#xff0c;Anaconda算是一个环境容器&#xff0c;也可以叫环境管理器。 作用&#xff1a;可以在Anaconda容器中为python项目创建不同的环境。在各个不同环境中可以安装不同版本的包并且各个环境互不影响。可以在使用不同项…

自动驾驶DCLC 功能规范

目录 1 概述Summary....................................................................................................... 4 1.1 目的Purpose....................................................................................................... 4 1.2 范围Ran…

每天学习一点点之 MySQL TINYINT

我已经不是第一次遇到关于 TINYINT 的问题了。在 MySQL 中&#xff0c;当我们将某个字段设置为 TINYINT&#xff0c;随着业务的扩展&#xff0c;我们可能会发现 TINYINT 的范围无法满足需求。这时需要修改字段属性。但如果表的数据量很大&#xff0c;或者由于分表导致涉及的表数…