1. 傳統的方法
1.1 相似檢索(特征提取,相似度計算)
技術框架:
算法結構:
目標:實現基於人類顏色感知的相似排序
主要模塊:顏色特征提出;特征相似度計算
1.1.1 顏色、紋理、形狀
a. 相似顏色檢索
統計RGB圖像中顏色,形成直方圖,轉化為向量。這種固定維度直方圖維度太高,可以用自編碼器降維。自編碼器是通過神經網絡提取針對樣本的通用特征的降維方法,隱藏層的維數小於輸入樣本的維數,最后還需要升維使隱藏層的輸出最大限度的保存圖像的主要特征,以使還原后的圖像與原圖像誤差達到最小。
也可以用聚類直方圖統計圖像的顏色成份,使喚K-means++對圖片Lab像素進行聚類 橫軸的顏色維數會減少。
相似度計算:色差距離(CIEDE200)
顏色差異多少算是有差距的。色差容忍度(Tolerance),感知均勻的色差距離,色差小於Just-Noticeable-Difference閾值,人類視覺對綠色差異不敏感,對藍色差異比較敏感,(不均勻)。CIE1931顏色空間 從人眼色差容忍度來計算差異\(\Delta E_{ab}^*=\sqrt{(L_2^*-L_1^*)^2+(a_2^*-a_1^*)^2+(b_2^*-b_1^*)^2}\),容忍橢圓,非感知均勻
CIELab顏色空間, 視覺感知均勻的顏色模型。 CIEDE2000,均勻性更好的距離\(\Delta E_{00}^{12}=\Delta E_{00}(L_1^*,a_1^*,b_1^*; L_2^*, a_2^*, b_2^*)=\sqrt{\left(\frac{\Delta L^\prime}{k_LS_L}\right)^2+\left(\frac{\Delta C^\prime}{k_CS_C}\right)^2+\left(\frac{\Delta H^\prime}{k_HS_H}\right)^2+R^T\left(\frac{\Delta C^\prime}{k_CS_C}\right)\left(\frac{\Delta H^\prime}{k_HS_H}\right)}\)
相似度計算:顏色直方圖距離(Earth Mover Distance 推土機距離 Wasserstein 距離)
兩個圖片的顏色特征直方圖之間的視覺相似度作為檢索結果的排序依據
EMD是兩個多維特征分布之間的非相似性度量,是一個傳統運輸分配問題。
場景屬於多對多分配,比如物資運送,多個供應商對多個需求客戶;土堆搬運,多個土堆對多個土坑;約束條件是要求雙方的節點總量相等,不同節點之間的成本不同;目標是分配的成本最小。比如多個土堆的量正好能填滿多個土坑;土坑在不同的位置,土堆在不同的位置;最近的土堆推到最近的土坑,如果多出來的土,或者不滿的坑,都從最近的位置去尋找解決
假定:有三個土堆的土量都是5個單位;三個土坑所能容納的土量分別是3、7、5;不同的土堆和土坑之間的距離不同,分別是1、2、3,最近的為1,最遠的為3;有一個搬運工,一趟只能搬運1單位的土
目標:以最小的行走距離EMD,將所有的土堆運輸到土坑並填平
解:貪心法。先往自己最近的坑推。於是Hole_1, Hole_3先平,Earth_1多出來的部分只能稍遠一點
計算EMD距離:\(3\times 1+2\times 2+5\times 1+5\times 1=17\)
順序 E1->H1:3; E1->H2:2; E2->H2:5; E3->H3:5.
場景:顏色特征直方圖
計算EMD距離:\(2.5\times 90\%+39.7\times3\%+17.4\times 6\%+27.4\times 1\%=4.795\)
其中2.5, 39.7等顏色距離權重是CIEDE2000距離。
思路: 對圖庫里的圖片算顏色直方圖(特征提取),對搜索圖片計算顏色直方圖(特征提取),然后計算EMD距離,對距離值排序,值比較小的是最接近的圖片。
b. 相似紋理檢索
紋理是圖像中的重復模式:元素或基元按一定規則排序。紋理特征:反映圖像中同質現象的視覺特征。
算法結構:目標是實現基於人類紋理感知的相似排序。先特征提取再做相似度計算。
紋理特征提取。特征空間:多方向、多尺度Gabor濾波器組。特征計算:Kmeans++聚類直方圖。
Gabor濾波器組:類似於人類的生物視覺系統,多頻率多尺度多方向。
頻域:屬於加窗傅立葉變換。空域:一個高斯核函數和正弦平面波的乘積。
復數:\(g(x,y;\lambda,\theta,\psi,\sigma,\gamma)=\exp\left(-\frac{x^{\prime2}+\gamma^2y^2}{2\sigma^2}\right)\exp\left(i\left(2\pi\frac{x^\prime}{\lambda}+\psi\right)\right)\)
實部:\(g(x,y;\lambda,\theta,\psi,\sigma,\gamma)=\exp\left(-\frac{x^{\prime2}+\gamma^2y^2}{2\sigma^2}\right)\cos\left(2\pi\frac{x^\prime}{\lambda}+\psi\right)\)
虛部:\(g(x,y;\lambda,\theta,\psi,\sigma,\gamma)=\exp\left(-\frac{x^{\prime2}+\gamma^2y^2}{2\sigma^2}\right)\sin\left(2\pi\frac{x^\prime}{\lambda}+\psi\right)\)
其中:\(x^\prime=x\cos\theta+y\sin\theta\), \(y^\prime=-x\sin\theta+y\cos\theta\)
例如Gabor濾波器:6頻率(尺度)8方向;頻率:1,2,3,4,5,6;尺寸:25,35,49,69,97,137;方向:0,22.5,45,67.5,90,112.5,135,157.5。
特征提取步驟:
- 彩色圖片灰度化
- 提取灰度圖的Gabor濾波器特征(減小原圖尺寸和卷積使用快速傅立葉變換的方法來提高計算速度)
- 6頻率(尺度)、8方向的Gabor
- 48個同尺寸的特征圖
- 每個像素對應48維的Gabor向量
- 使用Kmeans++聚類所有像素Gabor特征
- K根據數據集紋理復雜度而定
- 使用KD-tree加速
示例K=10:
特征相似度計算
紋理聚類直方圖:EMD;紋理距離:L2
c. 相似形狀檢索
PHOG形狀特征提取:
HOG直方圖方向數量:9
梯度方向直方圖金字塔:\(1\times1\), \(2\times2\), \(4\times4\);維數\(1\times1\times9+2\times2\times9+4\times4\times9=189\)
使用灰度圖后進行分塊,采用Sobel梯度圖或者Canny邊緣圖等得到每一塊的直方圖,對這些直方圖級聯拼到一塊得到PHOG的特征向量.
缺點:只檢驗圖形輪廓是否大體一致,比HOG的結果要粗糙。比如只有圖像是正着存儲的效果會好點,比如圖片里的人需要都是站立的等等。
特征相似度計算:
標准化歐氏距離:
\(S_i 為樣本集特征中每一維對應的標准差\)
\(Dist(P,Q)=\sqrt{\sum\limits_i\left(\frac{P_i-Q_i}{S_i}\right)^2}\)
直方圖相交(Histogram Intersection):
\(Sim(P,Q)=\sum\limits_{i=1}^{i=n}\min(P_i,Q_i)\)
1.1.2 局部特征點
a. 相似局部特征檢索
特征提取:
檢測出所有的局部特征點和特征描述子
\(4\times4 個8方向梯度方向直方圖=128維描述子\)
比如SIFT特征點,SIFT特征點有很多改變的形式比如SURF,Color-SIFT顏色層面,Affine-SIFT基本上是類似於線性的扭曲變形,Dense-SIFT把SIFT像HOG一樣進行疊起來,兩個圖片相互疊着,PCA-SIFT先用PCA降維再用SIFT。
相似度計算:計算兩個圖SIFT點集之間匹配的有多少對
b. 詞包 Bag Of Visual Word
圖片形式的詞包。借用自然語言處理里的方法。BoW model 忽略文本的語法和語序,用一組無序的單詞word來表達一段文字或一個文檔。
視覺的詞包 Bag of Visual Word
將一些某一類圖片的共有特征作為詞匯組件,比如人臉圖片的眼睛、鼻子等,自行車圖片的車輪、腳踏板等,並形成向量。
-
假定訓練集有M幅圖像,對訓練集進行預處理,包括圖像增強、分割、統一格式、統一規格等。
-
對每一幅圖像(將圖像打成小的patch,對每個patch提取SIFT特征)提取若干個SIFT特征(每幅圖像的SIFT特征數量不一樣)。每個特征是128維的描述子矢量。
-
對所有圖像的所有描述子特征矢量進行Kmeans聚類。設定K個聚類中心。給聚類中心取個名字叫視覺詞。
-
對每個圖像的每一個SIFT特征與k個聚類中心(視覺詞,這個集合即為視覺詞字典)計算距離(L1、L2),每個SIFT特征與最近的視覺詞(聚類中心)就認為該SIFT特征是該視覺詞,也認為該圖像包含一個這個視覺詞,每個圖像的SIFT特征與某個視覺詞最近的情況都統計起來,則在文本中即為該文本包含該單詞多少次即詞頻,文本出現某個單詞的次數,同樣圖像也可以統計出現視覺詞的次數,有了視覺詞頻就可以畫直方圖(圖像中k個視覺詞出現的詞頻),也有了向量,即k維向量。這樣類似文本,圖像就可以用K維向量來表示。
2. 基於深度學習DL的方法
2.1 遷移學習(特征提取)
遷移學習可以使用VGG16這樣成熟的物品分類的網絡,只訓練最后的softmax層,只需要幾千張圖片,使用普通的CPU就可以完成,而且模型的准確性不錯。
遷移學習思想:遷移學習假定不同的數據集之間,初級特征比如折線、邊角等都是相同的,因此不需要再重新訓練這些參數,直接使用就行。
遷移實現思路:將前面的網絡的層的學習率設置很小的值接近於0(\(\eta\approx 0\) 權重不更新\(\mathrm{w}(m+1)=\mathrm{w}(m)+\Delta\mathrm{w}(m)=\mathrm{w}(m)-\eta\frac{\partial J}{\partial \mathrm{w}}\)), 只學習后面的層。如果數據集小,只訓練最后一層。如果數據集大,多訓練幾層。
2.2 基於深度學習的二值哈希編碼
特征提取:
在ImageNet中的卷積神經網絡結構(如 AlexNet 5個卷積層和3個全連接層)基礎上在第7層(4096個神經元)與output層之間加一個隱層(全連接層)。這一層的激活函數使用 sigmoid 輸出值在0-1之間,設定閾值(比如0.5)將輸出二值化,並使用這一層降低維度(比如使用128維),將這一層輸出的01二值向量作為二值檢索向量。在卷積神經網絡的圖像分類訓練過程中,第7層輸出4096維的最接近分類結果的特征向量被降低維度和二值化為低維度的01向量。這種降維和二值操作表征圖像豐富(第7層4096維)。
加了一層之后,不再重新對整個網絡做訓練,而是用遷移學習的思路,復用ImageNet中得到的最終模型的前7層的權重,在此基礎上做fine-tuning微調,相當於前面的7層保持不變(學習率\(\eta\approx0\)),只訓練后面的第7層、第8層(新加的)、output層之間的權重。這樣新加的層能夠比較好的代表第7層所體現的特征。新加的層的輸出可以作為檢索的索引。最后一層output層輸出的是標簽,倒數第二層即第8層(新加的)輸出的01二值檢索向量基本上表示一類圖片,基本上相當於這一類圖片的檢索索引。
待檢索的圖片獲得二值檢索向量后,通過hash檢索,找到對應的類二值檢索索引,再對這一類的所有圖片對比第7層的4096維向量,計算距離,重新對距離排序得到檢索結果。
相較於傳統的方法結合顏色、紋理、形狀、關鍵點等,而且結合的過程中還要考慮每一種特征的權重,深度學習還是能夠相當於端到端的解決問題。
3. 檢索方法
在圖像檢索中,數據是海量和高維的,要快速地找到與某個數據最相似(距離最近)的數據或多個數據,可以使用類似索引的技術。最近鄰查找 Nearest Neighbor 如 K-dimensional tree, 近似最近鄰查找 Approximate Nearest Neighbor,如Locality Sensitive Hash
3.1 Kd-tree
多維度查詢方法。一種用於多維度檢索的二叉平衡樹.
構建Kd-tree
- 輸入: N 個 d 維的數據點,以2 個維度為例(x,y):(2,3),(5,4),(4,7),(9,6),(7,2),(8,1)
- 確定split 值:方差最大的維度, 如 x
- 在確定的split值所在的維度上的中值點(7, 2)作為節點,首次進行算法時為根節點
- 確定左右子樹
- 左子樹:split 維度上小於節點 (2,3),(5,4),(4,7)
- 右子樹:split 維度上大於節點 (8,1),(9,6)
- 對左右子樹分別循環以上步驟
最近鄰查找
類似二叉樹搜索,從根結點,根據構建過程中split所在維度進行比較,對左右子樹進行查詢,查到葉子節點后,回溯檢查另一半子空間是否有更近的點(歐氏距離)
路徑: (7,2)->(5,4)->(4,7)
回溯: (5,4)->(2,3)
3.2 局部敏感哈希 Locality Sensitive Hash
處理海量高維數據。2個相似度很高的數據以較大概率映射成同一個hash值,2個相似度低的數據以極低的概率映射成同一個hash值。傳統的哈希算法可能2個相近的數的hash后分到比較遠的桶,如使用hash函數\(Hash(x)=x\% 8\), \(Hash(255)=255\% 8 =7\), \(Hash(257)=257\% 8=1\), \(Hash(1023)=1023\% 8=7\), 255與257的hash值比較遠,255與1023的hash值比較近。要使得原始空間上分布離的近數hash后也能夠的近一點的hash桶,在哈希空間上分布的近一點,也即選用局部敏感哈希的函數。
將這一族 滿足以下條件的 hash 函數 \(H=\{h:S\rightarrow U\}\) 稱為是\((r_1,r_2,p_1,p_2)\)敏感的。
如果 兩人個數據的差異程度或者距離 \(d(O_1,O_2)\lt r_1\), 那么\(O_1\), \(O_2\) 分到一個桶或者相近的桶的概率 \(Pr[h(O_1)=h(O_2)]\geq p_1\)。即兩個足夠相似的數據,映射為同一hash值的概率足夠大。
如果 差異程度或者距離 \(d(O_1,O_2)\gt r_2\), 那么\(O_1\), \(O_2\) 分到一個桶或者相近的桶的概率 \(Pr[h(O_1)=h(O_2)]\leq p_2\)。即兩個足夠不相似的數據,映射為同一hash值的概率足夠小。
p-穩定分布
一個實數集\(\mathrm{R}\)上的分布\(\mathrm{D}\),如果存在\(p\geq 0\), 對任何 \(n\)個實數 \(v_1,\cdots,v_n\)(比如輸入圖像特征的向量)和\(n\)個滿足\(\mathrm{D}\)分布的變量\(X_1,\cdots,X_n\), 隨機變量 \(\sum_i v_i X_i\) (向量點乘,結果是一個數) 和 \(\sqrt[p]{\sum_i\mid v_i\mid^p}X\) (\(p\)(階)范數,結果是一個數)有相同的分布,其中\(X\) 是服從\(\mathrm{D}\) 分布的一個隨機變量, 則稱 \(\mathrm{D}\) 為一個 p-穩定分布。
\(p=1\) 是柯西分布。 \(p=2\) 為二階范數,\(\mathrm{D}\)是高斯分布。
p-穩定分布 使得可以估計給定向量在歐式空間下的\(p\)范數的長度 \(\parallel v\parallel_p\)。對於 \(\sqrt[p]{\sum_i\mid v_i\mid^p}X\) 不好計算,依據 p-穩定分布,\(\sqrt[p]{\sum_i\mid v_i\mid^p}X\) 與 \(\sum_i v_i X_i\) 同分布,可以用計算 \(\sum_i v_i X_i\) 來代替\(\sqrt[p]{\sum_i\mid v_i\mid^p}X\)。
對於 \(p=2\) 為二階范數,\(\mathrm{D}\)是高斯分布。 所以取滿足正態分布的一個數列,與某個圖像特征的向量做向量點乘,得到一個數值,這個數值與這個圖像特征的向量本身的2階范數(即向量元素絕對值的平方和再開方,代表向量的長度,也是一個數值), 有同分布的性質。
假設有兩個圖像特征的向量 \(\mathbf{v1}\), \(\mathbf{v2}\), 用這兩個特征分別與同一個正態分布的數列做向量點乘,所得到的2個數值在一維上的距離與 \(\mathbf{v1}\), \(\mathbf{v2}\) 在多維上的歐氏距離是同分布的。
選取p-stable Locality Sensitive Hash函數
\(h_{\mathbf{a},b}(\mathbf{v})=\lfloor\frac{\mathbf{a}\cdot\mathbf{v}+b}{r}\rfloor\): \(\mathcal{R}^d\rightarrow\mathcal{N}\)
把 \(d\) 維向量 \(\mathbf{v}\) 映射成為一條直線上的一個整數值。
在 p-stable 分布上獨立、隨機選取 \(d\) 維向量 \(\mathbf{a}\)。映射到直線上的分段長度 \(r\) (桶寬),在 \([0,r]\) 上均勻隨機選取偏移 \(b\)。對於 \((\mathbf{v1}, \mathbf{v2})\) 投射距離 \((\mathbf{a}\cdot \mathbf{v1}-\mathbf{a}\cdot \mathbf{v2})\) 與 \(\parallel \mathbf{v1}-\mathbf{v2}\parallel_p X\) 同分布,也即映射后遠近程度與映射前的遠近程度一樣,映射后的距離與映射前的距離一樣。
構建索引
由於是概率問題,還是有可能相似的數據不能投放到一個hash桶中,解決方法是用多個hash函數對向量進行hash運算。比如一個圖像特征的向量 \(\mathbf{v_i}\), 從LSH函數族中選取 \(k\) 個 hash 函數 \(h_1(), h_2(),\cdots, h_k()\) 計算 \(k\) 個 hash 值 \(h_1(\mathbf{v_i}), h_2(\mathbf{v_i}),\cdots, h_k(\mathbf{v_i})\)。在查詢的時候同樣對查詢向量 \(\mathbf{q}\) 用同樣的 \(k\) 個函數計算 \(h_1(\mathbf{q}), h_2(\mathbf{q}),\cdots, h_k(\mathbf{q})\)。 這兩組值之間只有一個對應位的值相等,就認為 \(\mathbf{v_i}\) 是查詢 \(\mathbf{q}\) 的一個近鄰。
實現:
- 對於 \(k\) 個具有 \((r_1,r_2,p_1,p_2)\) 局部敏感性的哈希原子函數 表示為函數 \(\mathcal{G}=\{g: S\rightarrow U^k\}\) 即 \(g(\mathbf{v})=(h_1(\mathbf{v}), h_2(\mathbf{v}),\cdots, h_k(\mathbf{v}))\), \(h_i\in H\)。
- 從 \(\mathcal{G}\) 獨立、隨機選取 \(L\) 個 LSH 函數 \(g_1,\cdots,g_L\)。
- 構建 \(L\) 個 LSH 的索引表,為所有數據點計算 \(g_i(\mathbf{v})\), \(i=1,\cdots, L\) 對於數據集中任意一點\(\mathbf{v}\),將其存儲到桶\(g_i(\mathbf{v})\)中
- 計算查詢的 \(L\) 個LSH值 \(g_1(\mathbf{q}), \cdots, g_L(\mathbf{q})\), 並在桶中搜索
工程中實際使用的方法:
每個向量 \(\mathbf{v}\) 經過 \(g(\mathbf{v})=(h_1(\mathbf{v}), h_2(\mathbf{v}),\cdots, h_k(\mathbf{v}))\) 生成 \(x_1,\cdots,x_k\)
構建索引表使用大素數 \(C\)。
\(H_1(x_1,\cdots,x_k)=(\sum\limits_{i=1}^k r_ix_i \mod C)\mod size\) 對表size 做 mod, 映射到某個桶里面,
\(H_2(x_1,\cdots,x_k)=(\sum\limits_{i=1}^k r^\prime_ix_i \mod C)\) 使用一個hash 函數將 \((x_1,\cdots,x_k)\)計算一個哈希值作為指紋。
[1] https://towardsdatascience.com/understanding-locality-sensitive-hashing-49f6d1f6134
[2] https://blog.csdn.net/JasonDing1354/article/details/38227085
[3] https://www.cnblogs.com/hxsyl/p/4627477.html