又拍圖片管家億級圖像之搜圖系統的兩代演進及底層原理
又拍圖片管家當前服務了千萬級用戶,管理了百億級圖片。當用戶的圖庫變得越來越龐大時,業務上急切的需要一種方案能夠快速定位圖像,即直接輸入圖像,然後根據輸入的圖像內容來找到圖庫中的原圖及相似圖,而以圖搜圖服務就是爲了解決這個問題。
本人有幸獨立負責並實施了整個以圖搜圖系統從技術調研、到設計驗證、以及最後工程實現的全過程。而整個以圖搜圖服務也是經歷了兩次的整體演進:從 2019 年初開始第一次技術調研,經歷春節假期,2019 年 3、4 月份第一代系統整體上線;2020 年初着手升級方案調研,經歷春節及疫情,2020 年 4 月份開始第二代系統的整體升級。
本文將會簡述兩代搜圖系統背後的技術選型及基本原理。
基礎概要
圖像是什麼?
與圖像打交道,我們必須要先知道:圖像是什麼?
答案:像素點的集合。
比如:
左圖紅色圈中的部分其實就是右圖中一系列的像素點。
再舉例:
假設上圖紅色圈的部分是一幅圖像,其中每一個獨立的小方格就是一個像素點(簡稱像素),像素是最基本的信息單元,而這幅圖像的大小就是 11 x 11 px 。
圖像的數學表示
每個圖像都可以很自然的用矩陣來表示,每個像素點對應的就是矩陣中的一個元素。
二值圖像
二值圖像的像素點只有黑白兩種情況,因此每個像素點可以由 0 和 1 來表示。
比如一張 4 * 4 二值圖像:
0 1 0 1
1 0 0 0
1 1 1 0
0 0 1 0
RGB 圖像
紅(Red)、綠(Green)、藍(Blue)作爲三原色可以調和成任意的顏色,對於 RGB 圖像,每個像素點包含 RGB 共三個通道的基本信息,類似的,如果每個通道用 8 bit 表示即 256 級灰度,那麼一個像素點可以表示爲:
([0 .. 255], [0 .. 255], [0 .. 255])
比如一張 4 * 4 RGB 圖像:
圖像處理的本質實際上就是對這些像素矩陣進行計算。
搜圖的技術問題
如果只是找原圖,也就是像素點完全相同的圖像,那麼直接對比它們的 MD5
值即可。然而,圖像在網絡的傳輸過程中,常常會遇到諸如壓縮、水印等等情況,而 MD5
算法的特點是,即使是小部分內容變動,其最終的結果卻是天差地別,換句話說只要圖片有一個像素點不一致,最後都是無法對比的。
對於一個以圖搜圖系統而言,我們要搜的本質上其實是內容相似的圖片,爲此,我們需要解決兩個基本的問題:
•把圖像表示或抽象爲一個計算機數據•這個數據必須是可以進行對比計算的
直接用專業點的話說就是:
•圖像的特徵提取•特徵計算(相似性計算)
第一代搜圖系統
特性提取 - 圖像抽象
第一代搜圖系統在特徵提取上使用的是 Perceptual hash
即 pHash
算法,這個算法的基本原理是什麼?
如上圖所示,pHash
算法就是對圖像整體進行一系列變換最後構造 hash 值,而變換的過程可以理解爲對圖像進行不斷的抽象,此時如果對另外一張相似內容的圖像進行同樣的整體抽象,那麼其結果一定是非常接近的。
特性計算 - 相似性計算
對於兩張圖像的 pHash
值,具體如何計算其相似的程度?答案是 Hamming distance
漢明距離,漢明距離越小,圖像內容越相似。
漢明距離又是什麼?就是對應位置不同比特位的個數。
例如:
第一個值: 0 1 0 1 0
第二個值: 0 0 0 1 1
以上兩個值的對應位置上有 2 個比特位是不相同的,因此它們的漢明距離就是 2 。
OK ,相似性計算的原理我們知道了,那麼下一個問題是:如何去計算億級圖片對應的億級數據的漢明距離?簡而言之,就是如何搜索?
在項目早期其實我並沒有找到一個滿意的能夠快速計算漢明距離的工具(或者說是計算引擎),因此我的方案進行了一次變通。
變通的思想是:如果兩個 pHash 值的漢明距離是接近的,那麼將 pHash 值進行切割後,切割後的每一個小部分大概率相等。
例如:
第一個值: 8 a 0 3 0 3 f 6
第二個值: 8 a 0 3 0 3 d 8
我們把上面這兩個值分割成了 8 塊,其中 6 塊的值是完全相同的,因此可以推斷它們的漢明距離接近,從而圖像內容也相似。
經過變換之後,其實你可以發現,漢明距離的計算問題,變成了等值匹配的問題,我把每一個 pHash 值給分成了 8 段,只要裏面有超過 5 段的值是完全相同的,那麼我就認爲他們相似。
等值匹配如何解決?這就很簡單了,傳統數據庫的條件過濾不就可以用了嘛。
當然,我這裏用的是 ElasticSearch
( ES
的原理本文就不介紹了,讀者可以另行了解),在 ES
裏的具體操作就是多 term
匹配然後 minimum_should_match
指定匹配程度。
爲什麼搜索會選擇 ElasticSearch
?第一點,它能實現上述的搜索功能;第二點,圖片管家項目本身就正在用 ES
提供全文搜索的功能,使用現有資源,成本是非常低的。
第一代系統總結
第一代搜圖系統在技術上選擇了 pHash
+ ElasticSearch
的方案,它擁有如下特點:
•pHash
算法計算簡單,可以對抗一定程度的壓縮、水印、噪聲等影響。•ElasticSearch
直接使用了項目現有資源,在搜索上沒有增加額外的成本。
當然這套系統的侷限性也很明顯:由於 pHash
算法是對圖像的整體進行抽象表示,一旦我們對整體性進行了破壞,比如在原圖加一個黑邊,就會幾乎無法判斷相似性。
爲了突破這個侷限性,底層技術截然不同的第二代搜圖系統應運而生。
第二代搜圖系統
特性提取
在計算機視覺領域,使用人工智能相關的技術基本上已經成了主流,同樣,我們第二代搜圖系統的特徵提取在底層技術上使用的是 CNN
卷積神經網絡。
CNN
卷積神經網絡這個詞讓人比較難以理解,重點是回答兩個問題:
•CNN
能幹什麼?•搜圖爲什麼能用 CNN
?
AI 領域有很多賽事,圖像分類是其中一項重要的比賽內容,而圖像分類就是要去判斷圖片的內容到底是貓、是狗、是蘋果、是梨子、還是其它對象類別。
CNN
能幹什麼?提取特徵,進而識物,我把這個過程簡單的理解爲,從多個不同的維度去提取特徵,衡量一張圖片的內容或者特徵與貓的特徵有多接近,與狗的特徵有多接近,等等等等,選擇最接近的就可以作爲我們的識別結果,也就是判斷這張圖片的內容是貓,還是狗,還是其它。
CNN
識物又跟我們找相似的圖像有什麼關係?我們要的不是最終的識物結果,而是從多個維度提取出來的特徵向量,兩張內容相似的圖像的特徵向量一定是接近的。
具體使用哪種 CNN
模型?
我使用的是 VGG16
,爲什麼選擇它?首先,VGG16
擁有很好的泛化能力,也就是很通用;其次,VGG16
提取出來的特徵向量是 512
維,維度適中,如果維度太少,精度可能會受影響,如果維度太多,存儲和計算這些特徵向量的成本會比較高。
向量搜索引擎
從圖像提取特徵向量的問題已經解決了,那麼剩下的問題就是:
•特徵向量如何存儲?•特徵向量如何計算相似性,即如何搜索?
對於這兩個問題,直接使用開源的向量搜索引擎 Milvus 就可以很好的解決,截至目前,Milvus 在我們的生產環境一直運行良好。
第二代系統總結
第二代搜圖系統在技術上選擇了 CNN
+ Milvus
的方案,而這種基於特徵向量的搜索在業務上也提供了更好的支持。
作者上一篇文章 Milvus 開發者專欄|以圖搜圖系統工程實踐 已經簡單的介紹過 Milvus,
這裏就不再多做介紹。如你對以圖搜圖技術感興趣, 你也可以閱讀我們過去分享過的其他以圖搜圖相關內容, 或是加入 Milvus 社區交流羣與我們交流:
本文轉載自公衆號 Node Python Go 全棧開發,作者 rifewang
| 歡迎加入 Milvus 社區
github.com/milvus-io/milvus | 源碼
milvus.io | 官網
milvusio.slack.com | Slack 社區
zhihu.com/org/zilliz-11/columns | 知乎
zilliz.blog.csdn.net | CSDN 博客
space.bilibili.com/478166626 | Bilibili