|
| 1 | +## 弱水三千,只取一瓢,当图像搜索遇见PostgreSQL(Haar wavelet) |
| 2 | + |
| 3 | +### 作者 |
| 4 | +digoal |
| 5 | + |
| 6 | +### 日期 |
| 7 | +2016-07-26 |
| 8 | + |
| 9 | +### 标签 |
| 10 | +PostgreSQL , haar wavelet , 图像搜索 , 图片去重 , 视频去重 , 搜索引擎 |
| 11 | + |
| 12 | +---- |
| 13 | + |
| 14 | +## 背景 |
| 15 | +图片搜索是继文字搜索后又一个比较常用的搜索引擎。 |
| 16 | + |
| 17 | +市面上常见的搜索引擎有谷歌、百度、搜狗等图片搜索引擎。 |
| 18 | + |
| 19 | +http://image.baidu.com/ |
| 20 | + |
| 21 | +http://images.google.com.hk |
| 22 | + |
| 23 | +例如在搜索引擎提供的接口中上层了一张雪人的图片,搜出来一堆和雪人近似的图片。 |
| 24 | + |
| 25 | + |
| 26 | + |
| 27 | +图片搜索是怎么做到的呢? |
| 28 | + |
| 29 | +万能的PostgreSQL绝不落下这么好玩的东东,通过PG万能的API,可以扩展它的图片搜索功能。 |
| 30 | + |
| 31 | +如果你对PostgreSQL扩展开发感兴趣,可以参考我写的文章 |
| 32 | + |
| 33 | +《找对业务G点, 体验酸爽 - PostgreSQL内核扩展指南》 |
| 34 | + |
| 35 | +https://yq.aliyun.com/articles/55981 |
| 36 | + |
| 37 | +## PostgreSQL 图像搜索插件背景技术 |
| 38 | +PostgreSQL的图像搜索插件使用了非常主流的Haar wavelet技术对图像进行变换后存储,可以参考WIKI和一篇关于HW的文献。 |
| 39 | + |
| 40 | +https://en.wikipedia.org/wiki/Haar_wavelet |
| 41 | + |
| 42 | +http://www.cs.toronto.edu/~kyros/courses/320/Lectures.2013s/lecture.2013s.10.pdf |
| 43 | + |
| 44 | +截取几页,注意烧脑。 |
| 45 | + |
| 46 | + |
| 47 | + |
| 48 | + |
| 49 | + |
| 50 | + |
| 51 | + |
| 52 | + |
| 53 | + |
| 54 | +## PostgreSQL 图像搜索插件介绍 |
| 55 | +依赖gd.h |
| 56 | + |
| 57 | +``` |
| 58 | +# yum install -y gd-devel |
| 59 | +``` |
| 60 | + |
| 61 | +下载安装imgsmlr |
| 62 | + |
| 63 | +``` |
| 64 | +$ git clone https://github.com/postgrespro/imgsmlr |
| 65 | +$ cd imgsmlr |
| 66 | +$ export PGHOME=/home/digoal/pgsql9.5 |
| 67 | +$ export PATH=$PGHOME/bin:$PATH:. |
| 68 | + |
| 69 | +$ make USE_PGXS=1 |
| 70 | +$ make USE_PGXS=1 install |
| 71 | +``` |
| 72 | + |
| 73 | +安装插件 |
| 74 | + |
| 75 | +``` |
| 76 | +$ psql |
| 77 | +psql (9.5.3) |
| 78 | +Type "help" for help. |
| 79 | +postgres=# create extension imgsmlr; |
| 80 | +CREATE EXTENSION |
| 81 | +``` |
| 82 | + |
| 83 | +imgsmlr新增了两个数据类型 |
| 84 | + |
| 85 | +| Datatype | Storage length | Description | |
| 86 | +| --------- |--------------: | ------------------------------------------------------------------ | |
| 87 | +| pattern | 16388 bytes | Result of Haar wavelet transform on the image | |
| 88 | +| signature | 64 bytes | Short representation of pattern for fast search using GiST indexes | |
| 89 | + |
| 90 | +gist 索引方法(支持pattern和signature类型), 以及KNN操作符,可以用于搜索相似度 |
| 91 | + |
| 92 | +| Operator | Left type | Right type | Return type | Description | |
| 93 | +| -------- |-----------| ---------- | ----------- | ----------------------------------------- | |
| 94 | +| <-> | pattern | pattern | float8 | Eucledian distance between two patterns | |
| 95 | +| <-> | signature | signature | float8 | Eucledian distance between two signatures | |
| 96 | + |
| 97 | +新增了几个函数 |
| 98 | + |
| 99 | +将图像的二进制转换为pattern类型,将pattern中存储的数据转换为signature类型 |
| 100 | + |
| 101 | +| Function | Return type | Description | |
| 102 | +| -------------------------- |-------------| --------------------------------------------------- | |
| 103 | +| jpeg2pattern(bytea) | pattern | Convert jpeg image into pattern | |
| 104 | +| png2pattern(bytea) | pattern | Convert png image into pattern | |
| 105 | +| gif2pattern(bytea) | pattern | Convert gif image into pattern | |
| 106 | +| pattern2signature(pattern) | signature | Create signature from pattern | |
| 107 | +| shuffle_pattern(pattern) | pattern | Shuffle pattern for less sensitivity to image shift | |
| 108 | + |
| 109 | +## PostgreSQL 图像搜索插件测试 |
| 110 | +导入一些图片,例如(越多越好) |
| 111 | + |
| 112 | + |
| 113 | + |
| 114 | +建立图片表 |
| 115 | + |
| 116 | +``` |
| 117 | +create table image (id serial, data bytea); |
| 118 | +``` |
| 119 | + |
| 120 | +导入图片到数据库 |
| 121 | + |
| 122 | +``` |
| 123 | +insert into image(data) select pg_read_binary_file('文件路径'); |
| 124 | +``` |
| 125 | + |
| 126 | +将图片转换成 patten 和 signature |
| 127 | + |
| 128 | +``` |
| 129 | +CREATE TABLE pat AS ( |
| 130 | + SELECT |
| 131 | + id, |
| 132 | + shuffle_pattern(pattern) AS pattern, |
| 133 | + pattern2signature(pattern) AS signature |
| 134 | + FROM ( |
| 135 | + SELECT |
| 136 | + id, |
| 137 | + jpeg2pattern(data) AS pattern |
| 138 | + FROM |
| 139 | + image |
| 140 | + ) x |
| 141 | +); |
| 142 | +``` |
| 143 | + |
| 144 | +创建索引 |
| 145 | + |
| 146 | +``` |
| 147 | +ALTER TABLE pat ADD PRIMARY KEY (id); |
| 148 | +CREATE INDEX pat_signature_idx ON pat USING gist (signature); |
| 149 | +``` |
| 150 | + |
| 151 | +近似度查询,例如查询与id = :id的图像相似的图像,按相似度排行,取出前10条 |
| 152 | + |
| 153 | +```sql |
| 154 | +SELECT |
| 155 | + id, |
| 156 | + smlr |
| 157 | +FROM |
| 158 | +( |
| 159 | + SELECT |
| 160 | + id, |
| 161 | + pattern <-> (SELECT pattern FROM pat WHERE id = :id) AS smlr |
| 162 | + FROM pat |
| 163 | + WHERE id <> :id |
| 164 | + ORDER BY |
| 165 | + signature <-> (SELECT signature FROM pat WHERE id = :id) |
| 166 | + LIMIT 100 |
| 167 | +) x |
| 168 | +ORDER BY x.smlr ASC |
| 169 | +LIMIT 10 |
| 170 | +``` |
| 171 | + |
| 172 | +这里可以用到KNN索引,快速按相似度排行输出结果。 |
| 173 | + |
| 174 | +## 小结 |
| 175 | +* PostgreSQL是一个非常强大的数据库,功能高度可定制。而且不需要动到PostgreSQL的内核。 安全可靠。 |
| 176 | + |
| 177 | +* 使用图像搜索的技术就是PostgreSQL功能扩展的例子,速度杠杠的,还记得我以前给出的关于地理位置近邻查询的性能指标吗。 |
| 178 | + |
| 179 | + 《PostgreSQL 百亿地理位置数据 近邻查询毫秒级反馈》 |
| 180 | + |
| 181 | + https://yq.aliyun.com/articles/2999 |
| 182 | + |
| 183 | +* 如果你对PostgreSQL扩展开发感兴趣,可以参考我写的文章 |
| 184 | + |
| 185 | + 《找对业务G点, 体验酸爽 - PostgreSQL内核扩展指南》 |
| 186 | + |
| 187 | + https://yq.aliyun.com/articles/55981 |
| 188 | + |
| 189 | +祝大家玩得开心,欢迎随时来 **阿里云促膝长谈** 业务需求 ,恭候光临。 |
| 190 | + |
| 191 | +阿里云的小伙伴们加油,努力做 **最贴地气的云数据库** 。 |
| 192 | + |
| 193 | + |
| 194 | + |
| 195 | + |
| 196 | + |
| 197 | +[Count](http://info.flagcounter.com/h9V1) |
| 198 | + |
| 199 | + |
0 commit comments