最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python+OpenCV實現(xiàn)圖像的全景拼接

 更新時間:2020年03月05日 09:51:46   作者:CancerWu  
這篇文章主要為大家詳細(xì)介紹了Python+OpenCV實現(xiàn)圖像的全景拼接,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了Python+OpenCV實現(xiàn)圖像的全景拼接的具體代碼,供大家參考,具體內(nèi)容如下

環(huán)境:python3.5.2 + openCV3.4

1.算法目的

將兩張相同場景的場景圖片進(jìn)行全景拼接。

2.算法步驟

本算法基本步驟有以下幾步:

步驟1:將圖形先進(jìn)行桶形矯正

沒有進(jìn)行桶形變換的圖片效果可能會像以下這樣:

圖片越多拼接可能就會越夸張。

本算法是將圖片進(jìn)行桶形矯正。目的就是來縮減透視變換(Homography)之后圖片產(chǎn)生的變形,從而使拼接圖片變得畸形。

步驟2:特征點(diǎn)匹配

本算法使用的sift算法匹配,它具有旋轉(zhuǎn)不變性和縮放不變性,具體原理在之后會補(bǔ)上一篇關(guān)于sift算法的文章,這里就不做詳細(xì)介紹。

在匹配特征點(diǎn)的過程中,透視矩陣選取了4對特征點(diǎn)計算,公式為

點(diǎn)的齊次坐標(biāo)依賴于其尺度定義,因此矩陣H也僅依賴尺度定義,所以,單應(yīng)性矩陣具有8個獨(dú)立的自由度。

如果在選取的不正確的特征點(diǎn),那么透視矩陣就可能計算錯誤,所以為了提高結(jié)果的魯棒性,就要去除這些錯誤的特征點(diǎn),而RANSAC方法就是用來刪除這些錯誤的特征點(diǎn)。

**RANSAC:**用來找到正確模型來擬合帶有噪聲數(shù)據(jù)的迭代方法。基本思想:數(shù)據(jù)中包含正確的點(diǎn)和噪聲點(diǎn),合理的模型應(yīng)該能夠在描述正確數(shù)據(jù)點(diǎn)的同時擯棄噪聲點(diǎn)。

RANSAC方法隨機(jī)獲取4對不同的特征匹配坐標(biāo),計算出透視矩陣H1,再將第二張圖的特征匹配點(diǎn)經(jīng)過這個矩陣H1映射到第一張圖的坐標(biāo)空間里,通過計算來驗證這個H1矩陣是否滿足絕大部分的特征點(diǎn)。
通過迭代多次,以滿足最多特征匹配點(diǎn)的特征矩陣H作為結(jié)果。

這樣正常情況就可以去除錯誤的特征點(diǎn)了,除非匹配錯誤的特征點(diǎn)比正確的還多。

下圖是我在嘉庚圖書館旁拍攝的照片的特征點(diǎn)匹配。

步驟3:利用得到的變換矩陣進(jìn)行圖片的拼接。

可以看出基本做到了無縫拼接。只是在色差上還是看得出銜接的部分存在。

實現(xiàn)結(jié)果

我在宿舍里又多照了幾組照片來實驗:
室內(nèi)宿舍場景的特征點(diǎn)匹配:

拼接結(jié)果:

在室內(nèi)的效果根據(jù)結(jié)果來看效果也還可以。

我測試了宿舍里景深落差較大的兩張圖片:

特征點(diǎn)匹配:

雖然距離較遠(yuǎn),但是還是可以粗略的匹配到特征點(diǎn)。

拼接結(jié)果:

從結(jié)果上來看可以看得出來,兩張圖片依然可以正確而粗略地拼接再一起,可以看得出是同一個區(qū)域。只是由于特征點(diǎn)不夠,在細(xì)節(jié)上景深落差較大的還是沒辦法完美地拼接。

import numpy as np
import cv2 as cv
import imutils

class Stitcher:
 def __init__(self):
 self.isv3 = imutils.is_cv3()

 def stitch(self,imgs, ratio = 0.75, reprojThresh = 4.0, showMatches = False):
 print('A')
 (img2, img1) = imgs
 #獲取關(guān)鍵點(diǎn)和描述符
 (kp1, des1) = self.detectAndDescribe(img1)
 (kp2, des2) = self.detectAndDescribe(img2)
 print(len(kp1),len(des1))
 print(len(kp2), len(des2))
 R = self.matchKeyPoints(kp1, kp2, des1, des2, ratio, reprojThresh)

 #如果沒有足夠的最佳匹配點(diǎn),M為None
 if R is None:
 return None
 (good, M, mask) = R
 print(M)
 #對img1透視變換,M是ROI區(qū)域矩陣, 變換后的大小是(img1.w+img2.w, img1.h)
 result = cv.warpPerspective(img1, M, (img1.shape[1] + img2.shape[1], img1.shape[0]))
 #將img2的值賦給結(jié)果圖像
 result[0:img2.shape[0], 0:img2.shape[1]] = img2

 #是否需要顯示ROI區(qū)域
 if showMatches:
 vis = self.drawMatches1(img1, img2, kp1, kp2, good, mask)
 return (result, vis)

 return result


 def detectAndDescribe(self,img):
 print('B')
 gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

 #檢查我們使用的是否是penCV3.x
 if self.isv3:
 sift = cv.xfeatures2d.SIFT_create()
 (kps, des) = sift.detectAndCompute(img, None)
 else:
 sift = cv.FastFeatureDetector_create('SIFT')
 kps = sift.detect(gray)
 des = sift.compute(gray, kps)

 kps = np.float32([kp.pt for kp in kps]) # **********************************
 #返回關(guān)鍵點(diǎn)和描述符
 return (kps, des)

 def matchKeyPoints(self,kp1, kp2, des1, des2, ratio, reprojThresh):
 print('C')
 #初始化BF,因為使用的是SIFT ,所以使用默認(rèn)參數(shù)
 matcher = cv.DescriptorMatcher_create('BruteForce')
 # bf = cv.BFMatcher()
 # matches = bf.knnMatch(des1, des2, k=2)
 matches = matcher.knnMatch(des1, des2, 2) #***********************************

 #獲取理想匹配
 good = []
 for m in matches:
 if len(m) == 2 and m[0].distance < ratio * m[1].distance:
 good.append((m[0].trainIdx, m[0].queryIdx))

 print(len(good))
 #最少要有四個點(diǎn)才能做透視變換
 if len(good) > 4:
 #獲取關(guān)鍵點(diǎn)的坐標(biāo)
 # 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)
 src_pts = np.float32([kp1[i] for (_, i) in good])
 dst_pts = np.float32([kp2[i] for (i, _) in good])

 #通過兩個圖像的關(guān)鍵點(diǎn)計算變換矩陣
 (M, mask) = cv.findHomography(src_pts, dst_pts, cv.RANSAC, reprojThresh)

 #返回最佳匹配點(diǎn)、變換矩陣和掩模
 return (good, M, mask)
 #如果不滿足最少四個 就返回None
 return None

 def drawMatches(img1, img2, kp1, kp2, matches, mask, M):
 # 獲得原圖像的高和寬
 h, w = img1.shape[:2]
 # 使用得到的變換矩陣對原圖像的四個角進(jìn)行變換,獲得目標(biāo)圖像上對應(yīng)的坐標(biāo)
 pts = np.float32([[0, 0], [0, h-1], [w-1, h-1], [w-1, 0]]).reshape(-1, 1, 2)
 dst = cv.perspectiveTransform(pts, M)
 matchesMask = mask.ravel().tolist()

 draw_params = dict(matchColor = (0, 255, 0),
  singlePointColor = None,
  matchesMask = matchesMask,
  flags = 2)
 img = cv.drawMatches(img1, kp1, img2, kp2, matches, None, **draw_params)

 return img

 def drawMatches1(self,img1, img2, kp1, kp2, metches,mask):
 print('D')
 (hA,wA) = img1.shape[:2]
 (hB,wB) = img2.shape[:2]
 vis = np.zeros((max(hA,hB), wA+wB, 3), dtype='uint8')
 vis[0:hA, 0:wA] = img1
 vis[0:hB, wA:] = img2
 for ((trainIdx, queryIdx),s) in zip(metches, mask):
 if s == 1:
 ptA = (int(kp1[queryIdx][0]), int(kp1[queryIdx][1]))
 ptB = (int(kp2[trainIdx][0])+wA, int(kp2[trainIdx][1]))
 cv.line(vis, ptA, ptB, (0, 255, 0), 1)

 return vis

# def show():
# img1 = cv.imread('image/sedona_left_01.png')
# img2 = cv.imread('image/sedona_right_01.png')
# img1 = imutils.resize(img1, width=400)
# img2 = imutils.resize(img2, width=400)
#
# stitcher = cv.Stitcher()
# (result, vis) = stitcher.stitch([img1, img2])
# # (result, vis) = stitch([img1,img2], showMatches=True)
#
# cv.imshow('image A', img1)
# cv.imshow('image B', img2)
# cv.imshow('keyPoint Matches', vis)
# cv.imshow('Result', result)
#
# cv.waitKey(0)
# cv.destroyAllWindows()
# show()

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python 輸出詳細(xì)的異常信息(traceback)方式

    Python 輸出詳細(xì)的異常信息(traceback)方式

    這篇文章主要介紹了Python 輸出詳細(xì)的異常信息(traceback)方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • 基于深度學(xué)習(xí)和OpenCV實現(xiàn)目標(biāo)檢測

    基于深度學(xué)習(xí)和OpenCV實現(xiàn)目標(biāo)檢測

    這篇文章主要介紹了通過使用OpenCV進(jìn)行基于深度學(xué)習(xí)的對象檢測以及使用OpenCV檢測視頻,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2021-12-12
  • Pycharm導(dǎo)包失敗問題及解決

    Pycharm導(dǎo)包失敗問題及解決

    這篇文章主要介紹了Pycharm導(dǎo)包失敗問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Python中位運(yùn)算的詳細(xì)用法教程

    Python中位運(yùn)算的詳細(xì)用法教程

    在Python中,位運(yùn)算是一種對二進(jìn)制數(shù)進(jìn)行操作的運(yùn)算方式,它們直接對二進(jìn)制位進(jìn)行操作,而不考慮這些位所表示的實際值,本文將詳細(xì)介紹Python中的位運(yùn)算符,需要的朋友可以參考下
    2024-08-08
  • 如何在python中實現(xiàn)線性回歸

    如何在python中實現(xiàn)線性回歸

    這篇文章主要介紹了如何在python中實現(xiàn)線性回歸,幫助大家更好的理解和學(xué)習(xí)Python,感興趣的朋友可以了解下
    2020-08-08
  • 你還在@微信官方?聊聊Python生成你想要的微信頭像

    你還在@微信官方?聊聊Python生成你想要的微信頭像

    這篇文章主要介紹了你還在@微信官方?我來教你用Python生成你想要的微信頭像功能,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-09-09
  • 教你如何用python開發(fā)一款數(shù)字推盤小游戲

    教你如何用python開發(fā)一款數(shù)字推盤小游戲

    這篇文章主要介紹了教你如何用python開發(fā)一款數(shù)字推盤小游戲,文中有非常詳細(xì)的代碼示例,喜對歡玩小游戲的或者正在學(xué)習(xí)python小游戲開發(fā)的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-04-04
  • Python?format字符串格式化函數(shù)的使用

    Python?format字符串格式化函數(shù)的使用

    本文主要介紹了Python?format字符串格式化函數(shù)的使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • python文件比較示例分享

    python文件比較示例分享

    本文介紹了Python比較兩個文本文件內(nèi)容,如果不同, 給出第一個不同處的行號和列號,大家參考使用吧
    2014-01-01
  • Python語言中的重要函數(shù)對象用法小結(jié)

    Python語言中的重要函數(shù)對象用法小結(jié)

    Python作為一種強(qiáng)大的編程語言,提供了多種高級函數(shù)對象,如lambda匿名函數(shù)、map()、reduce()函數(shù),以及迭代器和生成器的使用,本文給大家介紹Python語言中的重要函數(shù)對象用法,感興趣的朋友跟隨小編一起看看吧
    2024-09-09

最新評論

通化县| 梨树县| 连州市| 东兰县| 筠连县| 平乐县| 岳西县| 高雄县| 长岭县| 馆陶县| 武强县| 涪陵区| 丹阳市| 麻栗坡县| 西和县| 洛川县| 苗栗市| 元氏县| 岑溪市| 分宜县| 图片| 瓮安县| 和硕县| 武平县| 凤庆县| 高雄市| 泗水县| 大关县| 余干县| 厦门市| 蕲春县| 大方县| 阿图什市| 廉江市| 本溪市| 原阳县| 宜兴市| 平武县| 江山市| 信丰县| 芒康县|