OpenCV中常用的特征检测和提取算法包括:
- Harris:用于检测角点
- SIFT:用于检测斑点(blob)
- SURF:用于检测斑点
- FASF:用于检测角点
- BRIEF:用于检测斑点
- ORB:带方向的FAST算法和具有旋转不变性的BRIEF算法的组合,ORB = oFAST + rBRIEF
1、Harris算子在上一篇文章中详细描述原理,其他算子网上有很多博客,就不再重复造(chao)轮了。
2、SIFT算子主要思想是对图像进行尺度变换和模糊,从不同的尺度下去提取图像的特征,类似于模拟人眼观察世界,人眼既可以识别物体的整体特征,又能观察物体的细节特征。
3、SURF算子参考:https://www.cnblogs.com/gfgwxw/p/9415218.html
4、ORB算子是用改进的FAST算子进行特征提取,用改进的BRIEF算子进行特征描述。
在网上找了一段代码,想要对比一下SIFT算子和ORB算子特征检测及描述的效果,顺便总结一下python代码的实现规则。
# !/usr/bin/env python
# -*- coding:utf-8 -*-
from matplotlib import pylab as plt
import numpy as np
import cv2 as cv
# 读入图像
img_name_1 = "/home/lihoon/code/lesson02/mayun_1.jpg"
img_name_2 = "/home/lihoon/code/lesson02/mayun_2.jpg"
img_1 = cv.imread(img_name_1)
img_2 = cv.imread(img_name_2)
# 转换为灰度图像:图像处理一般都是灰度图像
gray_1 = cv.cvtColor(img_1, cv.COLOR_BGR2GRAY)
gray_2 = cv.cvtColor(img_2, cv.COLOR_BGR2GRAY)
# 实例化SIFT算子
sift = cv.xfeatures2d.SIFT_create()
# 分别对两张图像进行SIFT检测
kp_1, des_1 = sift.detectAndCompute(img_1, None)
kp_2, des_2 = sift.detectAndCompute(img_2, None)
# 显示特征点
img_res_1 = cv.drawKeypoints(img_1, kp_1, gray_1, color=(255, 0, 255))
img_res_2 = cv.drawKeypoints(img_2, kp_2, gray_2, color=(0, 0, 255))
cv.imshow("SIFT_image_1", img_res_1)
cv.imshow("SIFT_image_2", img_res_2)
# BFMatcher算法匹配
bf = cv.BFMatcher()
matches = bf.knnMatch(des_1, des_2, k=2)
# 筛选优质的匹配点
ratio = 0.75
good_features = []
for m, n in matches:
if m.distance < ratio * n.distance:
good_features.append([m])
# 将匹配的特征点绘制在一张图内
img_res = cv.drawMatchesKnn(img_1, kp_1, img_2, kp_2, good_features, None, flags=2)
cv.imshow("BFmatch", img_res)
cv.waitKey(0)
cv.destroyAllWindows()
# !/usr/bin/env python
# -*- coding:utf-8 -*-
from matplotlib import pylab as plt
import numpy as np
import cv2 as cv
# 读入图像
img_name_1 = "/home/lihoon/code/lesson02/mayun_1.jpg"
img_name_2 = "/home/lihoon/code/lesson02/mayun_2.jpg"
img_1 = cv.imread(img_name_1)
img_2 = cv.imread(img_name_2)
# 转换为灰度图像:图像处理一般都是灰度图像
gray_1 = cv.cvtColor(img_1, cv.COLOR_BGR2GRAY)
gray_2 = cv.cvtColor(img_2, cv.COLOR_BGR2GRAY)
# 实例化ORB算子
orb = cv.ORB_create()
kp_1, des_1 = orb.detectAndCompute(img_1, None)
kp_2, des_2 = orb.detectAndCompute(img_2, None)
# BFMatcher算子匹配
bf = cv.BFMatcher(cv.NORM_HAMMING, crossCheck=True)
matches = bf.match(des_1, des_2)
matches = sorted(matches, key=lambda x: x.distance)
img_3 = cv.drawMatches(img_1, kp_1, img_2, kp_2, matches[:180], img_2, flags=2)
cv.imshow("result", img_3)
cv.waitKey()
cv.destroyAllWindows()
结果呢,SIFT匹配的其实还是挺好的,因为用128维向量描述特征,存在误匹配,但是概率不太大;ORB算子用BRIEF算子描述特征,用了复杂的编码操作来描述,个人感觉重点没有放在特征点周围的像素上,匹配的效果相对差一些。
OpenCV调用特征检测算子的基本步骤是:
创建算子 如:orb = cv.orb_create()
检测特征 如:key_points = orb.detec(img, None)
特征描述 如:key_points, descriptors = orb.comput(img, key_points)
特征匹配 如:matches = matcher.match(des_1, des_2)