Opencv之Brute-force匹配器与Flann匹配器

文章目录

  • 1 测试图像
    • 1.1 peiqi.png
    • 1.2 peiqi_in_img.png
  • 2 Brute-force
    • 2.1 使用Orb描述符
    • 2.2 使用SIFT描述器
  • 3 Flann

1 测试图像

1.1 peiqi.png

1.2 peiqi_in_img.png

2 Brute-force

  暴力匹配使用第一组中一个特征的描述符,并使用一些距离计算将其与第二组中的所有其他特征进行匹配,并返回最近的一个。

2.1 使用Orb描述符

import numpy as np
import cv2 as cv


def test(target_path, match_path):
    img_target = cv.imread(target_path, cv.IMREAD_GRAYSCALE)
    img_match = cv.imread(match_path, cv.IMREAD_GRAYSCALE)
    orb = cv.ORB_create()
    kp_target, des_target = orb.detectAndCompute(img_target, None)
    kp_match, des_match = orb.detectAndCompute(img_match, None)
    bf = cv.BFMatcher(cv.NORM_HAMMING, crossCheck=True)
    matches = bf.match(des_target, des_target)
    matches = sorted(matches, key=lambda x: x.distance)
    img_draw = cv.drawMatches(img_target, kp_target, img_match, kp_match, matches[:10], None,
                              flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
    img_draw = cv.resize(img_draw, None, fx=0.5, fy=0.5)
    cv.imshow("", img_draw)
    cv.waitKey()


if __name__ == '__main__':
    test("peiqi.png", "peiqi_in_img.png")

  输出如下:
Opencv之Brute-force匹配器与Flann匹配器_第1张图片

2.2 使用SIFT描述器

import numpy as np
import cv2 as cv


def test(target_path, match_path):
    img_target = cv.imread(target_path, cv.IMREAD_GRAYSCALE)
    img_match = cv.imread(match_path, cv.IMREAD_GRAYSCALE)
    sift = cv.SIFT_create()
    kp_target, des_target = sift.detectAndCompute(img_target, None)
    kp_match, des_match = sift.detectAndCompute(img_match, None)
    bf = cv.BFMatcher()
    matches = bf.knnMatch(des_target, des_match, k=2)
    good = []
    for m, n in matches:
        if m.distance < 0.75 * n.distance:
            good.append([m])
    img_draw = cv.drawMatchesKnn(img_target, kp_target, img_match, kp_match, good, None,
                                 flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
    img_draw = cv.resize(img_draw, None, fx=0.5, fy=0.5)
    cv.imshow("", img_draw)
    cv.waitKey()


if __name__ == '__main__':
    test("peiqi.png", "peiqi_in_img.png")

  输出如下:
Opencv之Brute-force匹配器与Flann匹配器_第2张图片

3 Flann

  对于大型数据集,Flann的速度快于Brute-force:

import cv2 as cv


def test(target_path, match_path):
    img_target = cv.imread(target_path, cv.IMREAD_GRAYSCALE)
    img_match = cv.imread(match_path, cv.IMREAD_GRAYSCALE)
    sift = cv.SIFT_create()
    kp_target, des_target = sift.detectAndCompute(img_target, None)
    kp_match, des_match = sift.detectAndCompute(img_match, None)
    idx_params = dict(algorithm=1, trees=5)
    search_params = dict(checks=50)  # search_params = {}
    flann = cv.FlannBasedMatcher(idx_params, search_params)
    matches = flann.knnMatch(des_target, des_match, k=2)
    matches_mask = [[0, 0] for i in range(len(matches))]
    for i, (m, n) in enumerate(matches):
        if m.distance < 0.7 * n.distance:
            matches_mask[i] = [1, 0]
    draw_params = dict(matchColor=(0, 255, 0),
                       singlePointColor=(255, 0, 0),
                       matchesMask=matches_mask,
                       flags=cv.DrawMatchesFlags_DEFAULT)
    img_draw = cv.drawMatchesKnn(img_target, kp_target, img_match, kp_match, matches, None, **draw_params)
    img_draw = cv.resize(img_draw, None, fx=0.5, fy=0.5)
    cv.imshow("", img_draw)
    cv.waitKey()


if __name__ == '__main__':
    test("peiqi.png", "peiqi_in_img.png")

  输出如下:
Opencv之Brute-force匹配器与Flann匹配器_第3张图片


参考文献
【1】Opencv中文文档。

你可能感兴趣的:(Python,Python,Opencv,Brute匹配,Flann,因吉)