百万级图像抓取去重存档技术方案

2020-04-29 10:53:47 +08:00
 phpfpm

前情提要:

https://www.v2ex.com/t/665885

特别提醒,本文讨论的不是两张图片如何判断内容是否相似

实现的目标

抓取某论坛发布的主题和图片,根据图片特征判重标记。

硬件

云主机

阿里云(2c2g)服务器一台:某些服务的管理的公网出口(rabbitmq, 路由器管理等),基本不使用

阿里云 hk:proxy 出口

vultr sg:proxy 出口

物理机

db: i5-5200u/8g/hdd: mysql, rabbitmq

web:i5-4200u/8g/ssd: nginx/php/redis

nas:N3150/16g/hdd*n: samba

主要流程

列表页-详情页-图片 item:触发抓取

抓取:触发存储, 计算 md5 判重, 计算图片内容 hash

存储-校验-标记完成

计算 md5 判重-存储判重结果

计算图片内容 hash-redis 建立索引-查找 hash 重复-计算内容判重-存储判重结果

如何高效检索内容 hash 相近的图片

算了一些 hash,考虑汉明距离<=3 以内的作为 hash 接近的图片。

对于 128bit 的 hash,分为 4 组,如果汉明距离<=3, 至少有一组是完全一致的。

因此,将图片的内容 hash 分为四段存入 redis,建立倒排索引。

比如 id=123,hash=aaaabbbbccccdddd, 算法是 average,
存储这么几个数据到 redis:
sadd average:part1:aaaa => 123
sadd average:part1:bbbb => 123
sadd average:part1:cccc => 123
sadd average:part1:dddd => 123

这样下次搜索比如 aaaa000011112222 的判重的时候,就会命中
average:part1:aaaa 这个集合,从中取出 id 搜索对应的 hash 继续判重。

1M 量级的数据,四种 hash 算法,每种算法会分为 64k 个组,平均每个组 16 个 hash
那么对于一个新的图片需要判重 4 种 * 4 个分片 * 16 = 256 个 hash 比对
结合 redis 的读取时间,能压缩到几秒钟以内了。
存量数据花了三四天清洗完了,增量准实时。

剩下的结合索引优化等,继续提升效率。

1392 次点击
所在节点    问与答
7 条回复
wysnylc
2020-04-29 11:35:11 +08:00
还是折腾 hash
rrfeng
2020-04-29 13:51:42 +08:00
请问『内容 hash 相近』有什么意义?
fancy111
2020-04-29 13:54:06 +08:00
hash 相近==图片相近???
你不如搞图像识别去重,还说得过去一点。
imn1
2020-04-29 14:08:12 +08:00
@rrfeng
@fancy111
LZ 说的“内容 hash”是 image hash 的简称,就是图像识别,不是传统意义的字节哈希,看他的上一帖
rrfeng
2020-04-29 14:27:43 +08:00
还是简单提一下好……用『图像指纹』代替 hash 就不会歧义了。

所以本质上就是 100w * 128bit 的记录如何快速查汉明距离最短,分组是个简单有效的方法,但感觉应该有更好的算法。
phpfpm
2020-04-29 14:34:00 +08:00
@rrfeng 按照我现在的硬件这个查询效率我觉得差不多了,换一台好的服务器还能提高不少效率。
更好的算法也得基于更好的硬件,比如显卡加入什么的,愿闻其详
loadingimg
2020-05-03 23:30:37 +08:00
dhash 去重效果不错

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/667203

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX