Press "Enter" to skip to content

基于图像识别的图片定位方式研究

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

前言

 

虽然多数情况下照片的exif (Exchangeable image file format,图像元数据格式) 信息中已经包含GPS坐标,对它们的定位十分简单。但我们所能接触到的照片很少会是原片(脱去了exif),通常都不含任何有价值的信息,甚至有时候exif数据可能是被特意篡改的,这使得判断拍摄地点变得异常困难。我们可能需要人工提取图中的特征,与现实的各个可能地点进行比对,如果需要比对的地点足够多,对照片进行定位几乎是不可能的。

 

这种情况下,我们可以借助一些成熟的图像特征匹配技术,来代替人工。使用机器可以快速得出相似度最高的可能地点,大大提高处理的效率。

 

为了更好地解释图像检测的过程,本文会涉及一些基础的计算机视觉和神经网络概念。

 

工作原理

 

pytorch 实现了 torch 库 (C语言编写的后端) 的python接口,用于机器学习。它支持NVIDIA的CUDA技术,可以实现方便的硬件加速。

 

我们使用pytorch的 torchvision 来做图像处理和识别,torchvision提供了多个数据集和模型架构。

 

 

这是整个项目的重点,其性能直接决定了我们图像对比的准确性。

 

torchvision.models内置了多个模型用于图像检测相关用途,这里我们使用 ResNet

 

我们可以把图像数据读入ResNet,生成相应的样本,用于图像对比。

 

Pytorch的文档告诉我们,可以直接使用他们的预先训练模型,这样可以节省大量时间和精力,也能保证基本的图像识别性能。

 

 

pytorch可以通过传递pretrained=True参数来直接构建预训练模型。我们在这里封装了一个class,可以对resnet的多个版本进行方便调用。

 

 

下图展示了ResNet提取图像特征并分类的过程。我们图像对比的实现思路是,从ResNet提取图像的特征,然后求两个图像特征的相似度。

 

 

使用预训练的ResNet,需要对图像数据进行normalize(归一化)处理。pytorch文档的说明如下:

 

 

Histogram可以作为图像数据的描述,我们从ResNet输出的tensor (可以理解为特征向量),最终求得图像的histogram。

 

 

从图像读取到产生histogram的过程:

 

 

读取图像,进行归一化处理

 

使用torch.autograd()求导,计算出图像数据输入resnet之后的路径

 

得到resnet输出的tensor,也就是该图像的特征向量

 

tensor转换为numpy数组,进行flatten,我们会得到一列数值

 

每个数值除以所有数值之和,分别得到概率,这时的d_hist就是最终需要的histogram

 

 

 

接下来的工作是

 

 

根据histogram计算输入图像与目标图像的偏离度

 

 

 

distance方法如下,它支持多种计算方法,比较常用的是求差和cosine。

 

 

我们这里使用d1类型的distance计算,也就是简单求差取绝对值。

 

街景图数据

 

由于目前公开提供街景图数据的地图厂商很少,权衡之后我们选择 百度的方案 ,花销更小,基本也可以满足演示需求。

 

 

如果对数据全面程度和质量有更高要求,可以选择 Google的街景图place photos数据库 ,但收费不菲。

 

 

兴趣点搜集

 

POI (Place of Interest) 是一个互联网地图的概念,任何具有意义的地点都可以成为兴趣点,例如商店,学校大门,或者特定建筑物。

 

我们的做法是在确定中心点之后,在它附近搜集所有兴趣点的街景图,这样可以进一步增大命中几率。

 

如图,我们使用百度地图的POI搜集API,在中心点附近搜集十个类型的POI(因为API限制),并把它们的POI代码返回。

 

这样,我们就去抓取这些POI的街景图,并存储作为待对比的样本。

 

 

效果测试

 

我们下载一张中关村软件园国际软件大厦的正面部分照片,无明显标识,作为待定位图片:

 

 

为了节省时间,我们选择旁边的华夏科技大厦作为查询的中心点,通过百度地图查询的POI中应该会包含国际软件大厦,然后,行政区域限定为北京:

 

 

下图是华夏科技大厦:

 

 

偏离度(distance,越小则越接近)几乎相同的国际软件大厦局部照片:

 

 

由于华夏科技大厦的建筑风格与国际软件大厦类似,然后百度地图没有国际软件大厦正面照片,所以这个华夏大厦的正面照片以一个勉强的偏离度成为了最佳结果。

 

在数据源足够好的情况下,我们应该可以看到0.2以内的偏离度。

 

改进方向

 

增加街景图数据

 

这应该是最直接的改善途径,存在更多图片数据意味着有更多机会发现相似的图片,也就可以得到更精确的结果。

 

分布式计算

 

性能是一个巨大的问题,在使用CPU时,我们需要花费一两分钟处理几十张图片(计算histogram),CUDA可以把这个过程大大缩短。

 

 

但实际使用中我们可能需要处理上百张甚至上千张图片,分布式计算可以把重负荷的任务下发给GPU集群,从而成倍地加快处理速度,可以让这个系统变得实用。

 

使用街景图数据训练ResNet

 

Pytorch提供的pretrained数据来自ImageNet,并没有对街景图识别做针对性优化。如果我们需要更好的效果,应该使用自己的数据来训练。

 

这也是一个重要的改进方向。目前使用ResNet的识别效果差强人意,但有些时候,它得出的正确地点图片与query图片的distance并不会排在top5,使得识别的准确性大大下降。

 

参考资料

 

https://github.com/jm33-m0/img2location

 

https://github.com/pochih/CBIR

 

https://medium.com/@14prakash/understanding-and-implementing-architectures-of-resnet-and-resnext-for-state-of-the-art-image-cf51669e1624

 

https://pytorch.org/docs/stable/torchvision/models.html

Be First to Comment

发表评论

邮箱地址不会被公开。 必填项已用*标注