亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在python中利用opencv拼接圖像

發布時間:2021-04-30 15:48:48 來源:億速云 閱讀:381 作者:Leah 欄目:開發技術

如何在python中利用opencv拼接圖像?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

python是什么意思

Python是一種跨平臺的、具有解釋性、編譯性、互動性和面向對象的腳本語言,其最初的設計是用于編寫自動化腳本,隨著版本的不斷更新和新功能的添加,常用于用于開發獨立的項目和大型項目。

思路和方法

思路

1、提取要拼接的兩張圖片的特征點、特征描述符;
2、將兩張圖片中對應的位置點找到,匹配起來;
3、如果找到了足夠多的匹配點,就能將兩幅圖拼接起來,拼接前,可能需要將第二幅圖透視旋轉一下,利用找到的關鍵點,將第二幅圖透視旋轉到一個與第一幅圖相同的可以拼接的角度;
4、進行拼接;
5、進行拼接后的一些處理,讓效果看上去更好。

實現方法

1、提取圖片的特征點、描述符,可以使用opencv創建一個SIFT對象,SIFT對象使用DoG方法檢測關鍵點,并對每個關鍵點周圍的區域計算特征向量。在實現時,可以使用比SIFT快的SURF方法,使用Hessian算法檢測關鍵點。因為只是進行全景圖拼接,在使用SURF時,還可以調節它的參數,減少一些關鍵點,只獲取64維而不是128維的向量等,加快速度。
2、在分別提取好了兩張圖片的關鍵點和特征向量以后,可以利用它們進行兩張圖片的匹配。在拼接圖片中,可以使用Knn進行匹配,但是使用FLANN快速匹配庫更快,圖片拼接,需要用到FLANN的單應性匹配。
3、單應性匹配完之后可以獲得透視變換H矩陣,用這個的逆矩陣來對第二幅圖片進行透視變換,將其轉到和第一張圖一樣的視角,為下一步拼接做準備。
4、透視變換完的圖片,其大小就是最后全景圖的大小,它的右邊是透視變換以后的圖片,左邊是黑色沒有信息。拼接時可以比較簡單地處理,通過numpy數組選擇直接把第一張圖加到它的左邊,覆蓋掉重疊部分,得到拼接圖片,這樣做非常快,但是最后效果不是很好,中間有一條分割痕跡非常明顯。使用opencv指南中圖像金字塔的代碼對拼接好的圖片進行處理,整個圖片平滑了,中間的縫還是特別突兀。
5、直接拼效果不是很好,可以把第一張圖疊在左邊,但是對第一張圖和它的重疊區做一些加權處理,重疊部分,離左邊圖近的,左邊圖的權重就高一些,離右邊近的,右邊旋轉圖的權重就高一些,然后兩者相加,使得過渡是平滑地,這樣看上去效果好一些,速度就比較慢。如果是用SURF來做,時間主要畫在平滑處理上而不是特征點提取和匹配。

python_opencv中主要使用的函數

0、基于python 3.7和對應的python-opencv

1、cv2.xfeatures2d.SURF_create ([hessianThreshold[, nOctaves[, nOctaveLayers[, extended[, upright]]]]])
該函數用于生成一個SURF對象,在使用時,為提高速度,可以適當提高hessianThreshold,以減少檢測的關鍵點的數量,可以extended=False,只生成64維的描述符而不是128維,令upright=True,不檢測關鍵點的方向。

2、cv2.SURF.detectAndCompute(image, mask[, descriptors[, useProvidedKeypoints]])

該函數用于計算圖片的關鍵點和描述符,需要對兩幅圖都進行計算。

3、flann=cv2.FlannBasedMatcher(indexParams,searchParams)
match=flann.knnMatch(descrip1,descrip2,k=2)
flann快速匹配器有兩個參數,一個是indexParams,一個是searchParams,都用手冊上建議的值就可以。在創建了匹配器得到匹配數組match以后,就可以參考Lowe給出的參數,對匹配進行過濾,過濾掉不好的匹配。其中返回值match包括了兩張圖的描述符距離distance 、訓練圖(第二張)的描述符索引trainIdx 、查詢的圖(第一張)的描述符索引queryIdx 這幾個屬性。

4、M,mask=cv2.findHomography(srcPoints, dstPoints[, method[, ransacReprojThreshold[, mask]]])
這個函數實現單應性匹配,返回的M是一個矩陣,即對關鍵點srcPoints做M變換能變到dstPoints的位置。

5、warpImg=cv2.warpPerspective(src,np.linalg.inv(M),dsize[,dst[,flags[,borderMode[,borderValue]]]])
用這個函數進行透視變換,變換視角。src是要變換的圖片,np.linalg.inv(M)是④中M的逆矩陣,得到方向一致的圖片。

6、a=b.copy() 實現深度復制,Python中默認是按引用復制,a=b是a指向b的內存。

7、draw_params = dict(matchColor = (0,255,0),singlePointColor = (255,0,0),matchesMask = matchMask,flags = 2),img3 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params)
使用drawMatches可以畫出匹配的好的關鍵點,matchMask是比較好的匹配點,之間用綠色線連接起來。

核心代碼

import cv2
import numpy as np
from matplotlib import pyplot as plt
import time
MIN = 10
starttime=time.time()
img1 = cv2.imread('1.jpg') #query
img2 = cv2.imread('2.jpg') #train

#img1gray=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
#img2gray=cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
surf=cv2.xfeatures2d.SURF_create(10000,nOctaves=4,extended=False,upright=True)
#surf=cv2.xfeatures2d.SIFT_create()#可以改為SIFT
kp1,descrip1=surf.detectAndCompute(img1,None)
kp2,descrip2=surf.detectAndCompute(img2,None)

FLANN_INDEX_KDTREE = 0
indexParams = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
searchParams = dict(checks=50)

flann=cv2.FlannBasedMatcher(indexParams,searchParams)
match=flann.knnMatch(descrip1,descrip2,k=2)


good=[]
for i,(m,n) in enumerate(match):
 if(m.distance<0.75*n.distance):
 good.append(m)

if len(good)>MIN:
 src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1,1,2)
 ano_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1,1,2)
 M,mask=cv2.findHomography(src_pts,ano_pts,cv2.RANSAC,5.0)
 warpImg = cv2.warpPerspective(img2, np.linalg.inv(M), (img1.shape[1]+img2.shape[1], img2.shape[0]))
 direct=warpImg.copy()
 direct[0:img1.shape[0], 0:img1.shape[1]] =img1
 simple=time.time()

#cv2.namedWindow("Result", cv2.WINDOW_NORMAL)
#cv2.imshow("Result",warpImg)
 rows,cols=img1.shape[:2]
 
 for col in range(0,cols):
 if img1[:, col].any() and warpImg[:, col].any():#開始重疊的最左端
 left = col
 break
 for col in range(cols-1, 0, -1):
 if img1[:, 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 img1[row, col].any():#如果沒有原圖,用旋轉的填充
 res[row, col] = warpImg[row, col]
 elif not warpImg[row, col].any():
 res[row, col] = img1[row, col]
 else:
 srcImgLen = float(abs(col - left))
 testImgLen = float(abs(col - right))
 alpha = srcImgLen / (srcImgLen + testImgLen)
 res[row, col] = np.clip(img1[row, col] * (1-alpha) + warpImg[row, col] * alpha, 0, 255)

 warpImg[0:img1.shape[0], 0:img1.shape[1]]=res
 final=time.time()
 img3=cv2.cvtColor(direct,cv2.COLOR_BGR2RGB)
 plt.imshow(img3,),plt.show()
 img4=cv2.cvtColor(warpImg,cv2.COLOR_BGR2RGB)
 plt.imshow(img4,),plt.show()
 print("simple stich cost %f"%(simple-starttime))
 print("\ntotal cost %f"%(final-starttime))
 cv2.imwrite("simplepanorma.png",direct)
 cv2.imwrite("bestpanorma.png",warpImg)
 
else:
 print("not enough matches!")

看完上述內容,你們掌握如何在python中利用opencv拼接圖像的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

花莲市| 牟定县| 渭源县| 翁牛特旗| 伽师县| 商洛市| 高密市| 都匀市| 西乌珠穆沁旗| 太和县| 沾益县| 葫芦岛市| 荆门市| 宜兰市| 象山县| 瑞丽市| 萝北县| 台安县| 枣庄市| 小金县| 垣曲县| 德兴市| 台前县| 当阳市| 长沙县| 新建县| 多伦县| 满洲里市| 西城区| 嘉义县| 雷波县| 玉山县| 利辛县| 杭锦后旗| 崇文区| 年辖:市辖区| 扎鲁特旗| 阜平县| 崇阳县| 涿州市| 常宁市|