本文共 3211 字,大约阅读时间需要 10 分钟。
依赖gd.h
yum install -y gd-devel
下载安装imgsmlr $ git clone https://github.com/postgrespro/imgsmlr$ cd imgsmlr$ export PGHOME=/home/digoal/pgsql9.5$ export PATH=$PGHOME/bin:$PATH:.$ make USE_PGXS=1$ make USE_PGXS=1 install
安装插件
$ psqlpsql (9.5.3)Type "help" for help.postgres=# create extension imgsmlr;CREATE EXTENSION
imgsmlr新增了两个数据类型
数据类型 | 存储长度 | 描述 |
---|---|---|
pattern | 16388 bytes | 图片的哈尔小波变换结果 |
signature | 64 bytes | 模式的快速索引(GiST) |
gist 索引方法(支持pattern和signature类型), 以及KNN操作符,可以用于搜索相似度
操作符 | 左类型 | 右类型 | 返回类型 | 描述 |
---|---|---|---|---|
<-> | pattern | pattern | float8 | 两个模式的欧几里得距离 |
<-> | signature | signature | float8 | 两个特征的欧几里得距离 |
新增了几个函数
将图像的二进制转换为pattern类型,将pattern中存储的数据转换为signature类型函数 | 返回类型 | 描述 |
---|---|---|
jpeg2pattern(bytea) | pattern | 生产jpeg图片的模式 |
png2pattern(bytea) | pattern | 生产png图片的模式 |
gif2pattern(bytea) | pattern | 生产gif图片的模式 |
pattern2signature(pattern) | signature | 从模式中提取特征 |
shuffle_pattern(pattern) | pattern | 洗牌模式,不敏感图像的转变 |
2.1 建立图片表
create table image (id serial, data bytea);
2.2 导入图片到数据库
insert into image(data) select pg_read_binary_file('文件路径');
由于我的图片并没有权限上传到PostgreSQL服务端,不能当成本地文件使用。
CREATE TABLE hexdump (hex text);
创建临时表
xxd -p 4.jpg | tr -d '\n' > 4.hex;
图片文件转为16进制文件psql --host=xx.xx.xx.xx --port=1234 --username=root --dbname=postgres -c "COPY hexdump from STDIN" <4.hex;
通过输出流写入服务端的临时表insert into image(data) SELECT decode(hex, 'hex') FROM hexdump;
将16进制转为area 2.3 将图片转换成 patten 和 signature
CREATE TABLE pat AS ( SELECT id, shuffle_pattern(pattern) AS pattern, pattern2signature(pattern) AS signature FROM ( SELECT id, jpeg2pattern(data) AS pattern FROM image ) x );
2.4 创建索引
ALTER TABLE pat ADD PRIMARY KEY (id);CREATE INDEX pat_signature_idx ON pat USING gist (signature);
2.5 近似度查询,例如查询与id = :id的图像相似的图像,按相似度排行,取出前10条
SELECT id, smlrFROM( SELECT id, pattern <-> (SELECT pattern FROM pat WHERE id = :id) AS smlr FROM pat WHERE id <> :id ORDER BY signature <-> (SELECT signature FROM pat WHERE id = :id) LIMIT 100) xORDER BY x.smlr ASC LIMIT 10
这个smlr是越小越相似,可以试试下面这两张图片。
3.1 注意二方库是和jre环境相关的,不然会报错。
org.postgresql postgresql 42.1.4.jre7
3.2 通过输入流写入到bytea类型的字段
Class.forName("org.postgresql.Driver");connection= DriverManager.getConnection(url, user, password);FileInputStream in = ImageUtil.readImage(path);String insertSQL = "insert into image (id,data) values(?,?)";PreparedStatement ps = connection.prepareStatement(insertSQL);ps.setInt(1,1);ps.setBinaryStream(2, in, in.available());int count = ps.executeUpdate();
3.3 读取text字段
String sql = "select * from hexdump limit 1"; statement=connection.createStatement(); ResultSet resultSet=statement.executeQuery(sql); while(resultSet.next()){ ImageUtil.toFile(hexStringToBytes(resultSet.getString(1)),"/Users/work/1.jpg");}
3.3.2 读取bytea类型的字段
实际上bytea类型getString 就是hexdump的类型的x+text,故通过流读取比string合理String sql = "select * from image limit 1"; statement=connection.createStatement(); ResultSet resultSet=statement.executeQuery(sql); while(resultSet.next()){ ImageUtil.readBin2Image(resultSet.getBinaryStream(2), "/Users/work/2.jpg");}
安装文档:
如何插入文件:图片流转换工具: hex转byte[]:转载地址:http://vvmpa.baihongyu.com/