某图片网站整合yolo图片特征相似图片获取
某图片网站整合yolo图片特征相似图片获取
近日接手一图片网站,维护有200w张左右的摄影图片,整体部署在阿里云,其中图片文件保存在OSS-保存有加水印预览图/不同尺寸的裁剪图/原图等,RDS数据库-保存相关交易/用户等系统数据,两台负载均衡的ECS主机,部署php/java服务,nginx,es等.
原版相似图片搜索
相似图片,页面展示效果为,用户点击进入某个图片,系统将展示图库中与之类似的5张图片,选择 查看更多,将展示获取到的所有相似图片,并分页展示.
业务逻辑:获取数据库中该图片的所有标签,es搜索获取匹配结果的top5,并返回
查看更多的业务逻辑就比较蛋疼,原版处理逻辑为直接以图片title使用es搜索并返回结果.
新版相似图片搜索
分为两步,第一步获取es返回结果的全集,第二步根据图片深度特征计算相似图片得分排名,阈值过滤并返回.
具体实现逻辑
训练模型
首先,根据yolo数据集训练并获取类别特征模型,同时按照传统方法得到颜色特征,最终效果为:输入一张图片,返回top10的类别及得分集合,eg:[1_0.9,2_0.2,3_0.1,4_0.07....],并二值化得到23位hash,及23位颜色特征hash.
图片特征入库
有了训练模型,就需要对库中所有图片完成特征提取入库,便于后期即时的相似图片搜索.这里需要考虑一点,即用户当天上传图片的特征入库,因而事情需要如下几步:
- 获取rds库中所有的图片信息,及每日新增图片信息
- 根据图片信息获取oss无水印图片保存路径及下载地址
- 保存裁剪后的图片到公司内网文件服务器,便于本地获取,避免流文件读取速度慢/异常中断等问题影响
- 提取图片特征入库
针对上述情况,异步实现图片特征入库正合时宜,整体需要一台部署图片提取本地服务的GPU机器,开通外网端口的redis更新rds库中的图片信息(基于list实现队列),hbase集群保存图片特征并便于之后搜索的批量获取,mysql保存整个过程的图片处理状态及保障各类异常情况处理逻辑实现,具体代码实现为:
- 初始获取当前全部图片信息入库redis,并定时任务获取当天数据并入栈redis
- redis出栈图片数据,并调用oss接口,下载裁剪后的图片保存本地
- 定时获取已下载好的图片,提取特征并入库hbase,更新mysql图片状态
相似图片搜索
图片特征模糊搜索实现
因本次入库hbase的图片特征空间较小,可以保存在单表中,以rds对应的图片id作为rowKey保存.
模糊搜索业务流程:
- 获取es返回结果集,根据图片标签的不同,整体的返回结果全量一千左右
- 批量查询hbase获取对应的图片特征
- 类别hash特征与颜色hash特征汉明距离过滤,阈值多次测试获取,第一步粗筛
- 类别top3过滤,不包含即过滤
- 得分计算,top10碰撞,交叉熵计算得分
- 得分逆序排列返回
总结
整体业务实现难度不大,关键在于图片特征提取较为耗时,尤其是初始提取,差不多一周才完成全部图片特征的入库.其次是各语言之间的交互,旧版为php实现,新版采用php调用Java接口的形式完成迭代,再次就是流程较多,维护的定时任务与状态变量较多,整体的设计与管理需谨慎.