您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關利用python怎么對圖像進行全景拼接,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
1、基于SIFT的特征點的提取與匹配
利用Sift提取圖像的局部特征,在尺度空間尋找極值點,并提取出其位置、尺度、方向信息。
具體步驟:
1). 生成高斯差分金字塔(DOG金字塔),尺度空間構建
2). 空間極值點檢測(關鍵點的初步查探)
3). 穩定關鍵點的精確定位
4). 穩定關鍵點方向信息分配
5). 關鍵點描述
6). 特征點匹配
2、圖像配準
圖像配準是一種確定待拼接圖像間的重疊區域以及重疊位置的技術,它是整個圖像拼接的核心。本節采用的是基于特征點的圖像配準方法,即通過匹配點對構建圖像序列之間的變換矩陣,從而完成全景圖像的拼接。
變換矩陣H求解是圖像配準的核心,其求解的算法流程如下。
1)檢測每幅圖像中特征點。
2)計算特征點之間的匹配。
3)計算圖像間變換矩陣的初始值。
4)迭代精煉H變換矩陣。
5)引導匹配。用估計的H去定義對極線附近的搜索區域,進一步確定特征點的對應。
6)重復迭代4)和5)直到對應點的數目穩定為止。
設圖像序列之間的變換為投影變換
可用4組最佳匹配計算出H矩陣的8 個自由度參數hi=( i=0,1,...,7),并以此作為初始值。
為了提高圖像配準的精度,本節采用RANSAC算法對圖像變換矩陣進行求解與精煉,達到了較好的圖像拼接效果。RANSAC算法的思想簡單而巧妙:首先隨機地選擇兩個點,這兩個點確定了一條直線,并且稱在這條直線的一定范圍內的點為這條直線的支撐。這樣的隨機選擇重復數次,然后,具有最大支撐集的直線被確認為是樣本點集的擬合。在擬合的誤差距離范圍內的點被認為是內點,它們構成一致集,反之則為外點。根據算法描述,可以很快判斷,如果只有少量外點,那么隨機選取的包含外點的初始點集確定的直線不會獲得很大的支撐,值得注意的是,過大比例的外點將導致RANSAC算法失敗。在直線擬合的例子中,由點集確定直線至少需要兩個點;而對于透視變換,這樣的最小集合需要有4個點。
3、圖像融合
因為相機和光照強度的差異,會造成一幅圖像內部,以及圖像之間亮度的不均勻,拼接后的圖像會出現明暗交替,這樣給觀察造成極大的不便。 亮度與顏色均衡處理,通常的處理方式是通過相機的光照模型,校正一幅圖像內部的光照不均勻性,然后通過相鄰兩幅圖像重疊區域之間的關系,建立相鄰兩幅圖像之間直方圖映射表,通過映射表對兩幅圖像做整體的映射變換,最終達到整體的亮度和顏色的一致性。
具體實現:
import numpy as np import cv2 as cv from matplotlib import pyplot as plt if __name__ == '__main__': top, bot, left, right = 100, 100, 0, 500 img1 = cv.imread('1.jpg') img2 = cv.imread('2.jpg') srcImg = cv.copyMakeBorder(img1, top, bot, left, right, cv.BORDER_CONSTANT, value=(0, 0, 0)) testImg = cv.copyMakeBorder(img2, top, bot, left, right, cv.BORDER_CONSTANT, value=(0, 0, 0)) img1gray = cv.cvtColor(srcImg, cv.COLOR_BGR2GRAY) img2gray = cv.cvtColor(testImg, cv.COLOR_BGR2GRAY) sift = cv.xfeatures2d_SIFT().create() # find the keypoints and descriptors with SIFT kp1, des1 = sift.detectAndCompute(img1gray, None) kp2, des2 = sift.detectAndCompute(img2gray, None) # FLANN parameters FLANN_INDEX_KDTREE = 1 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) search_params = dict(checks=50) flann = cv.FlannBasedMatcher(index_params, search_params) matches = flann.knnMatch(des1, des2, k=2) # Need to draw only good matches, so create a mask matchesMask = [[0, 0] for i in range(len(matches))] good = [] pts1 = [] pts2 = [] # ratio test as per Lowe's paper for i, (m, n) in enumerate(matches): if m.distance < 0.7*n.distance: good.append(m) pts2.append(kp2[m.trainIdx].pt) pts1.append(kp1[m.queryIdx].pt) matchesMask[i] = [1, 0] draw_params = dict(matchColor=(0, 255, 0), singlePointColor=(255, 0, 0), matchesMask=matchesMask, flags=0) img3 = cv.drawMatchesKnn(img1gray, kp1, img2gray, kp2, matches, None, **draw_params) plt.imshow(img3, ), plt.show() rows, cols = srcImg.shape[:2] MIN_MATCH_COUNT = 10 if len(good) > MIN_MATCH_COUNT: src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2) dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2) M, mask = cv.findHomography(src_pts, dst_pts, cv.RANSAC, 5.0) warpImg = cv.warpPerspective(testImg, np.array(M), (testImg.shape[1], testImg.shape[0]), flags=cv.WARP_INVERSE_MAP) for col in range(0, cols): if srcImg[:, col].any() and warpImg[:, col].any(): left = col break for col in range(cols-1, 0, -1): if srcImg[:, col].any() and warpImg[:, col].any(): right = col break res = np.zeros([rows, cols, 3], np.uint8) for row in range(0, rows): for col in range(0, cols): if not srcImg[row, col].any(): res[row, col] = warpImg[row, col] elif not warpImg[row, col].any(): res[row, col] = srcImg[row, col] else: srcImgLen = float(abs(col - left)) testImgLen = float(abs(col - right)) alpha = srcImgLen / (srcImgLen + testImgLen) res[row, col] = np.clip(srcImg[row, col] * (1-alpha) + warpImg[row, col] * alpha, 0, 255) # opencv is bgr, matplotlib is rgb res = cv.cvtColor(res, cv.COLOR_BGR2RGB) # show the result plt.figure() plt.imshow(res) plt.show() else: print("Not enough matches are found - {}/{}".format(len(good), MIN_MATCH_COUNT)) matchesMask = None
實驗結果:
1、室內場景:
原圖1
原圖2
拼接后:
2、室外場景:
場景1:
原圖1
原圖2
拼接后:
場景2:
原圖1
原圖2
拼接后:
場景3:
原圖1
原圖2
拼接后:
總結:
本文分別針對室內和室外兩種情況對兩張圖像做全景拼接,發現室內情況下拼接的效果較為好。在室外場景1情況下,兩張圖像有近景和遠景結合,兩張圖像拼接后近景的圖像被放大并有一定程度的傾斜;在場景2中,兩張圖像都是遠景,拼接后的效果還不錯但是在拼接后圖像的中上方出現了拼接縫;場景3是在不同明亮程度下圖像的拼接可以發現拼接后的圖像出現明顯的明暗差距,并且拼接縫明顯兩張圖像沒有很好的拼接在一起,出現很多沒有重合的地方。
本實驗最初是用opencv-contrib3.4.5版本,但是由于sift的專利限制無法使用,隨后用opencv-contriv3.4.2代碼可以運行,不會出現問題。方法:先卸載當前版本的opencv并安裝:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-contrib-python==3.4.2.16
關于利用python怎么對圖像進行全景拼接就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。