python opencv orb特征点提取匹配然后图像拼接

opencv 基于ORB特征点图像拼接_特征点 warpperspective-CSDN博客

图像用这儿的

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!")

右边多出了一部分黑色的,应该是重复部分的宽

猜你喜欢

转载自blog.csdn.net/moonlightpeng/article/details/135458315