查了好多版本的资料,设置了opencv和contrib的版本,最终以子函数的形式,可以将两张图片融合成全景图:查的链接太多了,忘了保存了,如有侵权,立即删掉!
注:opencv-python版本:3.4.2.16
opencv-contrib-python版本:3.4.2.16
参考链接:https://www.cnblogs.com/skyfsm/p/7411961.html
https://www.pyimagesearch.com/2018/12/17/image-stitching-with-opencv-and-python/
https://blog.youkuaiyun.com/weixin_41010198/article/details/88575719
import cv2
import numpy as np
def stitch(img1,img2):
MIN = 10
surf=cv2.xfeatures2d.SURF_create(10000,nOctaves=4,extended=False,upright=True)
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
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
img3=direct
img4=warpImg
else:
print("not enough matches!")
img3=[]
img4=[]
return img3,img4
img1 = cv2.imread('C:\\Users\\YS\\Desktop\\img\\1.png') #query
img2 = cv2.imread('C:\\Users\\YS\\Desktop\\img\\2.png') #train
img3,img4=stitch(img1,img2)
cv2.imshow('p',img3)
cv2.waitKey(0)
cv2.destroyAllWindows()