OpenCV Sift特征匹配

OpenCV sift特征匹配通过提取两张图片的sift特征点,匹配后计算单应矩阵(该部分为SLAM相关知识,想了解的同学可以学习《视觉SLAM十四讲从入门到实践》【高翔】视觉SLAM十四讲_哔哩哔哩_bilibili

以下为OpenCV sift代码demo:

        opencv-python:4.8.1.78

        opencv-contrib-python:4.8.1.78

        numpy:1.24.3

import cv2
import numpy as np

def sift(img, map, ratio, Min_MatchCount):
    map = cv2.resize(map, (5472, int(map.shape[0] / map.shape[1] * 5472)))
    h1, w1 = img.shape[:2]
    h2, w2 = map.shape[:2]
    sift = cv2.SIFT().create()
    kp1, des1 = sift.detectAndCompute(img, None)
    kp2, des2 = sift.detectAndCompute(map, None)

    # 采用FLANN匹配算法
    # FLANN_INDEX_KDTREE = 1
    # index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
    # search_params = dict(checks=50)
    # flann = cv2.FlannBasedMatcher(index_params, search_params)
    # matches = flann.knnMatch(des1, des2, k=2)

    # 这里采用BF暴力匹配!
    bf = cv2.BFMatcher()
    matches = bf.knnMatch(des1, des2, k=2)

    good = []
    for m,n in matches:
        if m.distance < ratio * n.distance:
            good.append(m)


    if len(good) > Min_MatchCount:
   
        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)
        M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
        matchesMask = mask.ravel().tolist()
        pts = np.float32([[0, 0], [0, h1-1], [w1-1, h1-1], [w1-1, 0]]).reshape(-1, 1, 2)
        dst = cv2.perspectiveTransform(pts, M)
        map = cv2.polylines(map, [np.int32(dst)], True, (0,255,0),
                            3, lineType=cv2.LINE_AA)
        draw_params = dict(matchColor=(0,255,0),
                           singlePointColor = None,
                           matchesMask = matchesMask,
                           flags=2)
        result = cv2.drawMatches(img, kp1, map, kp2, good, None, **draw_params)
        cv2.imwrite("result.jpg", result)

        return M
    else:
        print("Not enough key-points pair")
        return None

if __name__ == "__main__":
    img1 = cv2.imread("filepath")
    img2 = cv2.imread("filepath")
    M = sift(img1, img2, 0.75, 8)
    print(f"homography for img1 and img2:{M}")
常见问题:

1. 报错:error: (-215) trainDescCollection[iIdx].rows < IMGIDX_ONE

     解决方法:匹配点过多,对匹配的图片进行resize,通过测试选择适合的resize大小。

(如有其他报错可在评论区评论,看到回复~)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值