前言

雖然多數情況下照片的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的過程:

  1. 讀取圖像,進行歸一化處理

  2. 使用torch.autograd()求導,計算出圖像數據輸入resnet之後的路徑

  3. 得到resnet輸出的tensor,也就是該圖像的特徵向量

  4. tensor轉換爲numpy數組,進行flatten,我們會得到一列數值

  5. 每個數值除以所有數值之和,分別得到概率,這時的d_hist就是最終需要的histogram

接下來的工作是

  1. 根據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,使得識別的準確性大大下降。

參考資料

相關文章