opencv 基于ORB特征点图像拼接_特征点 warpperspective-CSDN博客
图像用这儿的
python
import cv2
import numpy as np
from matplotlib import pyplot as plt
import time
import cv2.xfeatures2d
MIN = 10
'''
当描述子之间的距离大于两倍的最小距离时,认为匹配有误。
但有时候最小距离会非常小,所以设置一个经验值30作为下限。
'''
different_dis = 50
starttime = time.time()
img1 = cv2.imread("../stitichImages/bridLeft.jpg") # query
img2 = cv2.imread("../stitichImages/bridRight.jpg") # train
orb = cv2.ORB_create()
kp1, descrip1 = orb.detectAndCompute(img1, None)
kp2, descrip2 = orb.detectAndCompute(img2, None)
bf = cv2.BFMatcher.create()
matches = bf.match(descrip1, descrip2)
# match = sorted(matches, key = lambda x:x.distance)
# 计算最大距离和最小距离
min_distance = matches[0].distance
max_distance = matches[0].distance
for x in matches:
if x.distance < min_distance:
min_distance = x.distance
if x.distance > max_distance:
max_distance = x.distance
# 筛选匹配点
good_match = []
for x in matches:
if x.distance <= max(2 * min_distance, different_dis):
good_match.append(x)
print("good is "+ str(len(good_match)))
if len(good_match) > MIN:
src_pts = np.float32([kp1[m.queryIdx].pt for m in good_match]).reshape(-1, 1, 2)
ano_pts = np.float32([kp2[m.trainIdx].pt for m in good_match]).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!")
右边多出了一部分黑色的,应该是重复部分的宽