目录
本文使用环境为:
特征点检测算法AKAZE是一种广泛应用于图像处理领域的算法,它可以在不同尺度下提取图像的特征点,并具有尺度不变性和旋转不变性等优点。本文将概括介绍AKAZE算法的基本原理、实现过程以及其在实际应用中的表现。
AKAZE算法是基于尺度空间理论和图像金字塔的,它通过非线性扩散滤波来构建尺度空间,并在尺度空间中检测关键点。在AKAZE中,关键点的检测是通过一个称为“加速非线性扩散”的过程来实现的,该过程可以快速地生成尺度空间。此外,AKAZE还采用了M-LDB描述子来描述特征点的周围区域。
AKAZE算法在实际应用中表现出了良好的性能,可以应用于许多领域,如目标识别、图像配准、拼接等。例如,在目标识别中,AKAZE可以用于检测图像中的目标特征点,并通过特征匹配来识别出目标物体。此外,AKAZE还可以用于图像拼接中,通过对齐不同图像中的特征点来实现无缝拼接。
AKAZE算法具有以下优点:
然而,AKAZE算法也存在一些不足之处:
总之,特征点检测算法AKAZE是一种有效的图像特征提取方法,具有尺度不变性和旋转不变性等优点。在实际应用中表现出了良好的性能,可以应用于许多领域。然而,它也存在一些不足之处,如对光照变化敏感、对局部变化敏感以及需要手动设置参数等。未来可以进一步改进和完善AKAZE算法的性能和准确性。
代码需要的两张图,一个xml格式的文件,即:H1to3p.xml,如下:
- "1.0"?>
- <opencv_storage>
- <H13 type_id="opencv-matrix">
- <rows>3rows>
- <cols>3cols>
- <dt>ddt>
- <data>
- 7.6285898e-01 -2.9922929e-01 2.2567123e+02
- 3.3443473e-01 1.0143901e+00 -7.6999973e+01
- 3.4663091e-04 -1.4364524e-05 1.0000000e+00 data>H13>
- opencv_storage>


代码:
- from __future__ import print_function
- import cv2 as cv
- import numpy as np
- import argparse
- from math import sqrt
-
- # 读取两张图片
- parser = argparse.ArgumentParser(description='Code for AKAZE local features matching tutorial.')
- parser.add_argument('--input1', help='Path to input image 1.', default='graf1.png') # 在这里设置图像1
- parser.add_argument('--input2', help='Path to input image 2.', default='graf3.png') # 在这里设置图像2
- parser.add_argument('--homography', help='Path to the homography matrix.', default='H1to3p.xml') # 在这里设置H矩阵
- args = parser.parse_args()
-
- img1 = cv.imread(cv.samples.findFile(args.input1), cv.IMREAD_GRAYSCALE)
- img2 = cv.imread(cv.samples.findFile(args.input2), cv.IMREAD_GRAYSCALE)
- if img1 is None or img2 is None:
- print('Could not open or find the images!')
- exit(0)
- fs = cv.FileStorage(cv.samples.findFile(args.homography), cv.FILE_STORAGE_READ)
- homography = fs.getFirstTopLevelNode().mat()
-
- ## 初始化算法[AKAZE]
- akaze = cv.AKAZE_create()
- # 检测图像1和图像2的特征点和特征向量
- kpts1, desc1 = akaze.detectAndCompute(img1, None)
- kpts2, desc2 = akaze.detectAndCompute(img2, None)
-
- ## 基于汉明距离,使用暴力匹配来匹配特征点
- matcher = cv.DescriptorMatcher_create(cv.DescriptorMatcher_BRUTEFORCE_HAMMING)
- nn_matches = matcher.knnMatch(desc1, desc2, 2)
-
- ## 下面0.8默认参数,可以手动修改、调试
- matched1 = []
- matched2 = []
- nn_match_ratio = 0.8 # 最近邻匹配参数
- for m, n in nn_matches:
- if m.distance < nn_match_ratio * n.distance:
- matched1.append(kpts1[m.queryIdx])
- matched2.append(kpts2[m.trainIdx])
-
- ## 使用单应矩阵进行精匹配,进一步剔除误匹配点
- inliers1 = []
- inliers2 = []
- good_matches = []
- inlier_threshold = 2.5 # 如果两个点距离小于这个值,表明足够近,也就是一对匹配对
- for i, m in enumerate(matched1):
- col = np.ones((3,1), dtype=np.float64)
- col[0:2,0] = m.pt
-
- col = np.dot(homography, col)
- col /= col[2,0]
- dist = sqrt(pow(col[0,0] - matched2[i].pt[0], 2) +\
- pow(col[1,0] - matched2[i].pt[1], 2))
-
- if dist < inlier_threshold:
- good_matches.append(cv.DMatch(len(inliers1), len(inliers2), 0))
- inliers1.append(matched1[i])
- inliers2.append(matched2[i])
-
- ## 可视化
- res = np.empty((max(img1.shape[0], img2.shape[0]), img1.shape[1]+img2.shape[1], 3), dtype=np.uint8)
- cv.drawMatches(img1, inliers1, img2, inliers2, good_matches, res)
- cv.imwrite("akaze_result.png", res)
-
- inlier_ratio = len(inliers1) / float(len(matched1))
- print('A-KAZE Matching Results')
- print('*******************************')
- print('# Keypoints 1: \t', len(kpts1))
- print('# Keypoints 2: \t', len(kpts2))
- print('# Matches: \t', len(matched1))
- print('# Inliers: \t', len(inliers1))
- print('# Inliers Ratio: \t', inlier_ratio)
-
- cv.imshow('result', res)
- cv.waitKey()
