OpenCV-Python ORB特征匹配

第一步:导入库,图片,创建ORB对象

导入OpenCV库。

import cv2 as cv

在进行特征的提取之前,我们要读入两张图片(图片我就不提供了)。

image1 = cv.imread('1.png')
image2 = cv.imread('2.png')

这里我们使用的是ORB特征,所以要创建一个ORB对象: 

# 初始化ORB
orb = cv.ORB_create()

第二步:寻找关键点和描述子

创建之后,就是主要的寻找关键点和计算描述子:

 # 寻找关键点
 kp1 = orb.detect(img1)
 kp2 = orb.detect(img2)

 # 计算描述符
 kp1, des1 = orb.compute(img1, kp1) # 计算哪张图片的用哪张图片的关键点。
 kp2, des2 = orb.compute(img2, kp2)

找到了关键点可以画出关键点看一看:

# 画出关键点
outimg1 = cv.drawKeypoints(img1, keypoints=kp1, outImage=None)
outimg2 = cv.drawKeypoints(img2, keypoints=kp2, outImage=None)

# 这里是把两张图片在同一个窗口中显示。
import numpy as np
outimg3 = np.hstack([outimg1, outimg2])
cv.imshow("Key Points", outimg3)
cv.waitKey(0)

第三步:进行匹配

# 初始化 BFMatcher
 bf = cv.BFMatcher(cv.NORM_HAMMING)

 # 对描述子进行匹配
 matches = bf.match(des1, des2)

第四步:对匹配点进行筛选

# 计算最大距离和最小距离
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
       
'''
    当描述子之间的距离大于两倍的最小距离时,认为匹配有误。
    但有时候最小距离会非常小,所以设置一个经验值30作为下限。
'''
 good_match = []
 for x in matches:
     if x.distance <= max(2 * min_distance, 30):
         good_match.append(x)

第五步:绘制结果图

这里我们将绘制结果单独拿出来:

    draw_match(img1, img2, kp1, kp2, good_match)


def draw_match(img1, img2, kp1, kp2, match):
    outimage = cv.drawMatches(img1, kp1, img2, kp2, match, outImg=None)
    cv.imshow("Match Result", outimage)
    cv.waitKey(0)

完整代码

import cv2 as cv

def ORB_Feature(img1, img2):

    # 初始化ORB
    orb = cv.ORB_create()

    # 寻找关键点
    kp1 = orb.detect(img1)
    kp2 = orb.detect(img2)

    # 计算描述符
    kp1, des1 = orb.compute(img1, kp1)
    kp2, des2 = orb.compute(img2, kp2)

    # 画出关键点
    outimg1 = cv.drawKeypoints(img1, keypoints=kp1, outImage=None)
    outimg2 = cv.drawKeypoints(img2, keypoints=kp2, outImage=None)
   
    # 显示关键点
    # import numpy as np
    # outimg3 = np.hstack([outimg1, outimg2])
    # cv.imshow("Key Points", outimg3)
    # cv.waitKey(0)

    # 初始化 BFMatcher
    bf = cv.BFMatcher(cv.NORM_HAMMING)

    # 对描述子进行匹配
    matches = bf.match(des1, des2)

    # 计算最大距离和最小距离
    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

    # 筛选匹配点
    '''
        当描述子之间的距离大于两倍的最小距离时,认为匹配有误。
        但有时候最小距离会非常小,所以设置一个经验值30作为下限。
    '''
    good_match = []
    for x in matches:
        if x.distance <= max(2 * min_distance, 30):
            good_match.append(x)

    # 绘制匹配结果
    draw_match(img1, img2, kp1, kp2, good_match)

def draw_match(img1, img2, kp1, kp2, match):
    outimage = cv.drawMatches(img1, kp1, img2, kp2, match, outImg=None)
    cv.imshow("Match Result", outimage)
    cv.waitKey(0)

if __name__ == '__main__':
    # 读取图片
    image1 = cv.imread('1.png')
    image2 = cv.imread('2.png')
    ORB_Feature(image1, image2)

猜你喜欢

转载自blog.csdn.net/u013590327/article/details/126592894
今日推荐