摘要:如下圖所示,左右是兩張稍有不同的圖片,但都包含了廣州塔,左圖紅色框中標出了兩個感興趣的點,我期望找出它們在右圖的對應位置即對應點。
現在考慮一個全景圖拼接的應用場景,假設現有兩張圖片需要拼接成一張全景圖,這兩張圖片是通過相機右轉一定角度拍攝出來的,兩張圖片有部分取景是重疊的。如何實現拼接?當然這是一個不簡單的問題,我們現在只考慮實現拼接目標的第一步:找出圖像中重疊的內容,以及分別在兩張圖片中的位置。
如下圖所示,左右是兩張稍有不同的圖片,但都包含了廣州塔,左圖紅色框中標出了兩個感興趣的點,我期望找出它們在右圖的對應位置(即對應點)。
首先,要確定檢測哪些點,即哪些點是我們感興趣的?這可以使用Harris角檢測(見上篇筆記)方法來得到圖像的角點集合,然后通過設置合適的閾值和坐標范圍來找出我們感興趣的點。有了兩個圖像的興趣點集后,又如何能計算出它們的對應關系呢?這就需要解決兩個問題:
興趣點如何描述
興趣點之間的對應關系如何計算
興趣點描述興趣點,也即用Harris角檢測出來的結果,它只有坐標和像素值,只有這些信息不足以用于匹配,無法從另一張圖像中查找是否包含這個點。所以需要增加點的表征信息,一種方法是使用圍繞點周圍一小塊的圖像來描述這個點,如采用上圖中所標記的方式,即:以興趣點為中心劃出一個小矩形,將區域內所有像素值以一向量進行存儲,用這個向量來描述這個興趣點,那么此向量稱為興趣點描述符(interest point descriptor,下簡稱IPD)。
下面實現一個函數,為所有角點生成IPD:
def get_desc(image, filtered_coords, wid = 5): #image為原圖像,filtered_coords為角點的坐標,wid為矩形的“半徑” desc = [] for coords in filtered_coords: ipd = image[coords[0] - wid : coords[0] + wid + 1, coords[1] - wid : coords[1] + wid + 1].flatten() if ipd.shape[0] > 0: desc.append(ipd) return desc興趣點相關度
如何確定左圖中的某個興趣點,對應右圖中的某個興趣點?對應關系,不一定完全是等價關系,即兩個點雖然是對應關系,但它們對應的IPD并不完全相同。因為我們這里討論的找對應點的方法,允許兩張圖像在亮度、縮放上有一定的區別。所以兩個點的對應關系不能用IPD等價來匹配,而是要采用相似度或相關度來計算,相關度越高,它們越可能是對應關系。而相關度,可以使用現成的數學模型——皮爾遜相關系數(Pearson"s r,也被稱為皮爾森相關系數r,下簡稱r系數)來表示。所以,計算兩個點的對應關系就轉化為計算兩個IPD的r系數。
r系數被廣泛用于度量兩個變量之間的相關(線性相關)程度,它是兩個變量之間的協方差和標準差的商,一種等價表達式為標準分的均值:
r =
I1和I2為樣本集,μ1為I1的平均值,μ2為I2的平均值,σ1為I1的標準差,σ2為I2的標準差,上式計算結果即為r系數,范圍為-1到1。 r系數為正且越大,表示I1和I2同時趨向于它們各自的平均值,變化方向一致,相關度越高。系數為0意味著兩個變量之間沒有線性關系。
把兩個點對應的IPD代入上述公式的I,可得到兩個點的相關程度。所以找兩個圖像之間興趣點的對應關系,計算步驟是:
分別對兩個圖像應用Harris角檢測,得到圖像1的興趣點集1,和圖像2的興趣點集2
設定IPD的矩形大小,計算所有興趣點的IPD,得到IPD_SET_1和IPD_SET_2兩個集合
設定r系數的閾值,如0.5,即相關度在[0.5,1]之間我們才考慮,那么,對IPD_SET_1中指定的某個IPD,計算它與IPD_SET_2中所有IPD的r系數,若最大的r系數落在[0.5,1]區間,則其對應的IPD是最相關的。
下面實現一個IPD匹配函數,傳入兩個IPD集合,找出所有r系數符合給定閾值的(即認為有對應關系的)IPD:
def match(desc1, desc2, threshold = 0.5): n = len(desc1[0]) count1 = len(desc1) count2 = len(desc2) d = -np.ones((count1, count2)) #每個圖1的IPD,其對應的力2的IPD下標初始化為-1 for i in range(count1): ipd1 = desc1[i] d1 = (ipd1 - np.mean(ipd1)) / np.std(ipd1) for j in range(count2): ipd2 = desc2[j] if ipd1.shape[0] == ipd2.shape[0]: #忽略位于邊緣的IPD d2 = (ipd2 - np.mean(ipd2)) / np.std(ipd2) r = np.sum(d1 * d2) / (n - 1) if r > threshold: d[i, j] = r #i為圖像1角點坐標, j為符合閾值的圖像2角點坐標 ndx = np.argsort(-d) #將d的列降序排列,第0列即為r系數最大的 match_index_array = ndx[:, 0] #只保留第0列 return match_index_array
上述的函數為圖1的每個IPD,從右邊找到最佳的匹配(如果存在),但這還不夠,因為這不代表對右邊的這個IPD來說,左邊的的這個IPD是它的最佳匹配,所以,如果使用兩向匹配,互相認為是最佳的,我們才認為是對應關系,這樣效果會更好一些,雙向匹配的函數實現:
def match_twosided(desc1, desc2, threshold = 0.5): m_12 = match(desc1, desc2, threshold) m_21 = match(desc2, desc1, threshold) for i,j in enumerate(m_12): if j >= 0 and m_21[j] != i: m_12[i] = -1 #非雙向匹配的,置為-1,上層應該忽略之 return m_12例子
下面代碼使用以上的兩向匹配方法找出兩張圖像的對應點,并用白色線連接起來,看一下效果,兩張圖像是并排顯示的:
從圖中可以看出,兩個圖像中的廣州塔上的關鍵角點基本能找到對應的位置,但圖像的底部即建筑物的角點,與右圖的建筑物連接起來,即使它們不是相同的建筑物,這是因為這些角點看起來很像,準確點講,相關度(r系數)很高,所以被認為是對應點。
從這個例子也可以看出,要準確的找到對象在圖像間的對應點,還需要考慮一些因素,來使效果更佳:
為興趣點定義一個范圍,比如上面例子,如果只關注塔尖的興趣點,得出的效果令人滿意
在尋找對應關系時,可限定對應點的y坐標的距離不能超過一定范圍(如50個像素,根據實際應用而定),這樣可以有效排除一些雖然r系數高,但事實上不對應的點。
代碼如下,注意點的疏密可以通過參數微調:
from PIL import Image import matplotlib.pyplot as plt import numpy as np from scipy.ndimage import filters from skimage.feature import corner_peaks def harris_eps(im, sigma=3): #harris角檢測,見上個筆記 imx = np.zeros(im.shape) filters.gaussian_filter(im, (sigma,sigma), (0,1), imx) imy = np.zeros(im.shape) filters.gaussian_filter(im, (sigma,sigma), (1,0), imy) Wxx = filters.gaussian_filter(imx*imx,sigma) Wxy = filters.gaussian_filter(imx*imy,sigma) Wyy = filters.gaussian_filter(imy*imy,sigma) Wdet = Wxx*Wyy - Wxy**2 Wtr = Wxx + Wyy return Wdet * 2 / (Wtr + 1e-06) # def get_desc(image, filtered_coords, wid = 5): # 省略,見上文 # def match_twosided(desc1, desc2, threshold = 0.5): # 省略,見上文 im1 = np.array(Image.open("tower-left.jpg").convert("L")) im2 = np.array(Image.open("tower-right.jpg").convert("L")) coords_1 = corner_peaks(harris_eps(im1, sigma=1), min_distance=3, threshold_abs=0, threshold_rel=0.1) coords_2 = corner_peaks(harris_eps(im2, sigma=1), min_distance=3, threshold_abs=0, threshold_rel=0.1) desc1 = get_desc(im1, coords_1, wid=6) desc2 = get_desc(im2, coords_2, wid=6) match_index_array = match_twosided(desc1, desc2, threshold=0.5) im3 = np.concatenate((im1, im2), axis=1) #將兩個圖像左右合并成一個,以便顯示 plt.gray() plt.imshow(im3) for ipd_index_1,ipd_index_2 in enumerate(match_index_array): if ipd_index_2 != -1: x = [coords_1[ipd_index_1][4], coords_2[ipd_index_2][5] + im1.shape[1]] y = [coords_1[ipd_index_1][0], coords_2[ipd_index_2][0]] if np.abs(y[0] - y[1]) < 50: #這里限制了對應點之間的y坐標距離 plt.plot(x, y, "w", alpha=0.5) #連接兩個對應點 plt.plot(coords_1[:, 1], coords_1[:, 0], "+r", markersize=5) #畫圖1角點坐標 plt.plot(coords_2[:, 1] + im1.shape[1], coords_2[:, 0], "+r", markersize=5) #畫圖2角點坐標 plt.axis("off") plt.show()小結
從實例中可以看到,本文使用的描述點的和匹配的方法,存在誤配的情況,矩形大小的設置也會影響匹配的結果,而且它也不適用于在圖像被旋轉和縮放的情況下使用,近年,關于這方面的研究也在不斷取得進步,下一筆記將介紹一種稱為尺度不變特征轉換(Scale-invariant feature transform 或 SIFT)的算法,此算法應用非常廣。
你還可以查看我的其它筆記
參考資料wiki 皮爾遜積矩相關系數
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/37647.html
摘要:圖像矩圖像矩或稱幾何矩是由在年提出的。矩給出了對圖像形狀的一種度量。使用建議的第二種采樣方法即以圖像中心進行高斯分布采樣,長度使用,然后在基礎上增加了旋轉的描述以及快速的計算方法,這種方法被稱為。 ORB(Oriented FAST and Rotated BRIEF)可用來替代SIFT(或SURF),它對圖像更具有抗噪特性,是一種特征檢測高效算法,其速度滿足實時要求,可用于增強圖像匹...
摘要:學習筆記七數學形態學關注的是圖像中的形狀,它提供了一些方法用于檢測形狀和改變形狀。學習筆記十一尺度不變特征變換,簡稱是圖像局部特征提取的現代方法基于區域圖像塊的分析。本文的目的是簡明扼要地說明的編碼機制,并給出一些建議。 showImg(https://segmentfault.com/img/bVRJbz?w=900&h=385); 前言 開始之前,我們先來看這樣一個提問: pyth...
摘要:降采樣的目的是為了綜合所有不同清晰度的圖像進行關鍵點提取,這種關鍵點攜帶了不同清晰度的信息,對縮放具有不變性。是對的一種改進,主要特點是快速。的達到維,導致的比較耗時,使用哈爾小波轉換得到的方向,讓的降到維,減少了一半,提高了匹配速度。 尺度不變特征變換(Scale-invariant feature transform, 簡稱SIFT)是圖像局部特征提取的現代方法——基于區域/圖像塊...
摘要:接下來的學習筆記本人都將使用來代替。庫中提供的很多圖像操作都是分別作用于某個通道的數據。是最流行的開源色彩管理庫之一。目前只支持在增加和。模塊支持從圖像對象創建或的對象,方便被使用和顯示。模塊對圖像或指定區域的每個通道進行統計,包括等。 介紹 《Programming Computer Vision with Python》是一本介紹計算機視覺底層基本理論和算法的入門書,通過這本收可以...
閱讀 3737·2021-11-24 09:39
閱讀 2622·2019-08-30 15:54
閱讀 1165·2019-08-30 13:01
閱讀 3441·2019-08-28 18:30
閱讀 1636·2019-08-26 17:44
閱讀 3604·2019-08-26 11:31
閱讀 2430·2019-08-26 10:40
閱讀 1257·2019-08-26 10:27