opencv成长之路:特征点检测与图像匹配
- 格式:doc
- 大小:30.50 KB
- 文档页数:8
Python是一门功能强大的编程语言,而OpenCV则是一款开放源代码的计算机视观方面的库。
特征点匹配是计算机视觉领域中非常关键和基础的技术之一。
本文将介绍Python和OpenCV中常用的特征点匹配算法。
一、SIFT算法尺度不变特征变换(Scale-Invariant Feature Transform,SIFT)是一种用于提取图像局部特征的算法。
它能够在不同尺度和旋转角度上找到关键点,并且对图像的缩放、旋转保持不变性。
SIFT算法主要分为四个步骤:尺度空间极值检测、关键点定位、关键点方向确定和关键点描述。
在OpenCV中,可以使用cv2.xfeatures2d.SIFT_create()函数来创建SIFT对象,然后调用detectAndCompute()方法来提取关键点和描述符。
二、SURF算法加速稳健特征检测(Speeded-Up Robust Features,SURF)是一种基于Hessian矩阵的特征提取算法。
它比SIFT算法更快速,并且在某些情况下比SIFT算法具有更好的性能。
SURF算法也可以实现尺度和旋转不变性。
在OpenCV中,可以使用cv2.xfeatures2d.SURF_create()函数来创建SURF对象,并同样调用detectAndCompute()方法来提取关键点和描述符。
三、ORB算法Oriented FAST and Rotated BRIEF(ORB)是一种基于FAST关键点检测和BRIEF描述符的算法。
它在速度和性能之间取得了很好的平衡,具有较快的速度和较好的检测性能。
ORB算法对旋转具有不变性,但对于尺度变换的不变性较差。
在OpenCV中,可以使用cv2.ORB_create()函数来创建ORB对象,然后同样调用detectAndCompute()方法来提取关键点和描述符。
四、匹配算法特征点提取之后,就需要进行特征点的匹配。
常用的特征点匹配算法包括暴力匹配、FLANN匹配等。
pythonopencv3基于ORB的特征检测和BF暴力匹配knn匹配flann匹配Python OpenCV3中的ORB特征检测和BF暴力匹配以及FLANN匹配是计算机视觉中常用的技术,用于在图像中寻找相似的特征点并进行匹配。
下面将详细介绍这些技术以及如何使用它们。
一、ORB特征检测ORB(Oriented FAST and Rotated BRIEF)是一种用于检测图像特征的算法。
它结合了FAST特征检测和BRIEF特征描述子,并对其进行了改进,以便在实时性和准确性之间取得较好的平衡。
使用OpenCV中的ORB特征检测算法需要使用以下步骤:1. 创建ORB对象:使用cv2.ORB_create(方法创建ORB对象。
3. 绘制特征点:使用cv2.drawKeypoints(方法绘制特征点,传入原始图像、特征点和输出图像。
二、BF暴力匹配BF(Brute-Force)暴力匹配是一种简单但较慢的特征点匹配算法。
它通过计算两组特征点之间的欧氏距离,找到距离最近的特征点对。
使用BF暴力匹配算法需要使用以下步骤:1. 创建BFMatcher对象:使用cv2.BFMatcher_create(方法创建BFMatcher对象。
2. 匹配特征点:调用BFMatcher对象的match(方法,传入两组特征描述子,方法将返回最佳匹配的特征点对。
3. 绘制匹配结果:使用cv2.drawMatches(方法绘制匹配结果,传入原始图像和两组特征点。
三、FLANN匹配FLANN(Fast Approximate Nearest Neighbors)是一种快速近似最近邻算法,它可以在大型数据集上进行高效的最近邻。
在图像匹配中,它可以加速特征点匹配的过程。
使用FLANN匹配算法需要使用以下步骤:1. 创建FLANN匹配器:使用cv2.FlannBasedMatcher(方法创建FLANN匹配器对象。
2. 创建索引:调用BFMatcher对象的knnMatch(方法,传入两组特征描述子和最近邻数k,方法将返回最佳匹配的特征点对。
OpenCV图像拼接的原理主要分为两个阶段:图像对齐/配准(image alignment/Registration)和图像合成/融合(image Compositing)。
在图像对齐/配准阶段,主要包括以下步骤:
1. 特征点检测与图像匹配:这是确定两张需要拼接的图像之间相同部分的关键步骤,通过检测并比对两张图片的特征点来确定如何对齐这两张图片。
2. 计算图像间的变换矩阵:根据特征点的匹配结果,计算出对齐两张图片所需要的仿射变换矩阵。
3. 自动校准:这一步是为了更精确地对齐图像,可能需要进行一些微调。
4. 图像变形:使用上一步计算出的变换矩阵,将一张图片变形为另一张图片的形状。
在图像合成/融合阶段,主要包括以下步骤:
5. 计算接缝:为了使拼接后的图像看起来更自然,需要在两张图片之间创建一个接缝。
这一步会考虑到颜色、亮度等因素,使得接缝处不易被人眼察觉。
6. 图像融合:将接缝处的像素进行特殊处理,使得它们能够融入周围环境,从而得到最终的全景图或多重视图。
此外,OpenCV还提供了Stitcher类及其stitch方法用于实现图像拼接。
这些函数和类使得用户可以方便地调用上述算法,而无需自己编写复杂的代码来实现这些功能。
特征匹配和透视变换是计算机视觉领域中的重要技术,它们广泛应用于图像处理、目标识别、机器人导航等领域。
在opencv中,特征匹配和透视变换是两个非常重要的功能模块,能够帮助开发者实现各种复杂的图像处理任务。
本文将为大家介绍opencv中特征匹配和透视变换的相关知识和应用实例。
一、特征匹配特征匹配是计算机视觉领域中的一项基础技术,它的主要作用是在两幅图像中寻找相似的特征点,并将它们进行匹配。
在opencv中,特征匹配主要依靠SIFT(尺度不变特征变换)算法和SURF(加速稳健特征)算法来实现。
这两种算法都能够在图像中提取出关键点和它们的描述子,然后根据描述子的相似度来进行匹配。
特征匹配在图像配准、目标跟踪等领域中有着广泛的应用。
比如在图像配准中,我们可以利用特征匹配来将两幅图像进行配准,使它们在同一坐标系下对齐;在目标跟踪中,我们可以通过特征匹配来实现目标的快速识别和跟踪。
特征匹配是计算机视觉中非常重要的一环,它为图像处理和分析提供了基础支持。
二、透视变换透视变换是一种常用的图像变换技术,它可以将原始图像投影到一个新的空间中,从而实现图像的旋转、放缩、重构等操作。
在opencv 中,透视变换主要依靠透视变换矩阵来实现,该矩阵能够将原始图像的坐标映射到新空间中的坐标。
透视变换在计算机视觉领域中有着广泛的应用。
比如在图像校正中,我们可以利用透视变换来对图像进行校正,使其在视觉上更加真实和准确;在三维重构中,我们可以通过透视变换来还原三维场景的视图,从而实现对场景的深度理解和分析。
透视变换是计算机视觉中一个非常重要的图像处理技术,它为图像的变换和重构提供了重要手段。
三、opencv中的特征匹配和透视变换实例下面我们以一个例子来演示opencv中特征匹配和透视变换的应用。
假设我们有两幅图像A和B,我们希望通过特征匹配和透视变换将图像B对齐到图像A上。
1、我们利用SIFT算法在图像A和B中提取特征点,并计算它们的描述子。
Opencv中特征点提取和特征匹配算法详解(ORBSIFTSURFFAST)OpenCV是一个开源的计算机视觉库,提供了许多用于图像处理和计算机视觉任务的算法和函数。
特征点提取和特征匹配是计算机视觉中常用的任务之一,可以在图像中找到具有独特性质的特征点,并使用这些特征点进行图像匹配、物体识别和姿态估计等任务。
在OpenCV中,有多种特征点提取和特征匹配算法可供选择,其中包括ORB、SIFT、SURF和FAST 等。
ORB(Oriented FAST and Rotated BRIEF)是一种基于FAST角点检测和BRIEF描述符的特征点提取和特征匹配算法。
它的主要优势在于计算速度较快,适用于实时的计算机视觉应用。
ORB算法首先使用FAST角点检测算法在图像中检测角点,然后计算角点的Oriented FAST角度和尺度。
接下来,在每个角点周围的区域中计算二进制描述符,用于描述角点的特征。
最后,使用二进制描述符进行特征匹配,可以使用暴力匹配、近邻算法或FLANN算法等进行匹配。
SIFT(Scale-Invariant Feature Transform)是一种基于尺度不变特征变换的特征点提取和特征匹配算法。
SIFT算法通过构建尺度空间和特征点检测器来提取具有尺度不变性的特征点。
在尺度空间中,SIFT算法使用不同的尺度和方向的高斯滤波器来检测具有独特性质的特征点。
然后,通过计算特征点周围区域的梯度和方向来为每个特征点计算描述符。
最后,可以使用距离度量或RANSAC算法进行特征点的匹配。
SURF(Speeded-Up Robust Features)是一种基于加速鲁棒特征(speeded-up robust features)的特征点提取和特征匹配算法。
SURF算法主要通过构建尺度空间和计算积分图像来加速特征点提取和匹配的过程。
在尺度空间中,SURF算法使用高斯滤波器来检测不同尺度的特征。
然后,通过计算每个特征点周围区域的Haar小波响应来计算特征点的描述符。
OpenCV——SIFT特征检测与匹配SIFT特征和SURF特征⽐较⽐较项⽬SIFT SURF尺度空间极值检测使⽤⾼斯滤波器,根据不同尺度的⾼斯差(DOG)图像寻找局部极值使⽤⽅形滤波器,利⽤海森矩阵的⾏列式值检测极值,并利⽤积分图加速运算关键点定位通过邻近信息插补来定位与SIFT类似⽅向定位通过计算关键点局部邻域的⽅向直⽅图,寻找直⽅图中最⼤值的⽅向作为关键点的主⽅向通过计算特征点周围像素点x,y⽅向的哈尔⼩波变换,将x、y⽅向⼩波变换的和向量的最⼤值作为特征点⽅向特征描述⼦是关键点邻域⾼斯图像梯度⽅向直⽅图统计结果的⼀种表⽰,是16*8=128维向量是关键点邻域2D离散⼩波变换响应的⼀种表⽰,是16*4=64维向量应⽤中的主要区别通常在搜索正确的特征时更加精确,当然也更加耗时描述⼦⼤部分基于强度的差值,计算更快捷SIFT特征基本介绍SIFT(Scale-Invariant Feature Transform)特征检测关键特征:建⽴尺度空间,寻找极值关键点定位(寻找关键点准确位置与删除弱边缘)关键点⽅向指定关键点描述⼦建⽴尺度空间,寻找极值⼯作原理1. 构建图像⾼斯⾦字塔,求取DOG,发现最⼤与最⼩值在每⼀级2. 构建的⾼斯⾦字塔,每⼀层根据sigma的值不同,可以分为⼏个待级,最少有4个。
关键点定位我们在像素级别获得了极值点的位置,但是更准确的值应该在亚像素位置,如何得到--这个过程称为关键点(准确/精确)定位。
删除弱边缘--通过Hassian矩阵特征值实现,⼩于阈值⾃动舍弃。
关键点⽅向指定求得每⼀层对应图像的梯度,根据给定的窗⼝⼤⼩计算每个⾼斯权重,sigma=scale*1.5, 0-360之间建⽴36个直⽅图Bins找最⾼峰对应的Bin,⼤于max*80%的都保留这样就实现了旋转不变性,提⾼了匹配时候的稳定性⼤约有15%的关键点会有多个⽅向关键点描述⼦拟合多项式插值寻找最⼤Peak得到描述⼦ = 4*4*8=128构造函数cv::xfeatures2d::SIFT::create(int nfeatures = 0,int nOctaveLayers = 3, --⾼斯⾦字塔乘积数double contrastThreshold = 0.04, --对⽐度double edgeThreshold = 10, --边缘阈值,⼀般默认10就⾏double sigma = 1.6)1 #include <opencv2/opencv.hpp>2 #include <opencv2/xfeatures2d.hpp>3 #include <iostream>45using namespace cv;6using namespace cv::xfeatures2d;7using namespace std;89int main(int argc, char** argv) {10 Mat src = imread("test.jpg", IMREAD_GRAYSCALE);11if (src.empty()) {12 printf("could not load image...\n");13return -1;14 }15 namedWindow("input image", CV_WINDOW_AUTOSIZE);16 imshow("input image", src);1718// SIFT特征点检测19int minHessian = 100;20 Ptr<SIFT> detector = SIFT::create(minHessian);//和surf的区别:只是SURF→SIFT21 vector<KeyPoint> keypoints;22 detector->detect(src, keypoints, Mat());//找出关键点2324// 绘制关键点25 Mat keypoint_img;26 drawKeypoints(src, keypoints, keypoint_img, Scalar::all(-1), DrawMatchesFlags::DEFAULT);27 imshow("KeyPoints Image", keypoint_img);2829 waitKey(0);30return0;31 }。
SIFT(尺度不变特征变换)是一种用于检测和描述图像中的关键特征点的算法。
在 OpenCV 中,SIFT 算法提供了用于检测和匹配特征点的功能。
以下是一些与OpenCV 中 SIFT 特征点匹配相关的指标和步骤:
SIFT 特征点检测:
1.导入 OpenCV:
2.读取图像:
3.初始化 SIFT 检测器:
4.检测关键点和计算描述符:
SIFT 特征点匹配:
1.使用 BFMatcher 进行特征点匹配:
这里使用的是 Brute-Force 匹配器(BFMatcher),knnMatch返回每个查询描述符的最佳两个匹配。
2.应用比率测试来筛选匹配:
这个比率测试是一种常见的方法,用于剔除不够精确的匹配。
3.可视化匹配结果:
匹配指标:
在进行特征点匹配后,可以使用不同的指标来评估匹配的好坏。
一些常用的指标包括:
•匹配点数量:len(good_matches)给出了匹配的特征点数量。
•匹配比率:通过计算len(good_matches) / len(kp1)或len(good_matches) / min(len(kp1), len(kp2))可以得到匹配比率。
•单应性矩阵(Homography Matrix):如果你要估计两幅图像之间的单应性变换,可以使用cv2.findHomography函数,并根据单应性矩阵计算匹配的准确性。
这些指标可以帮助你评估 SIFT 特征点匹配的性能。
在实际应用中,你可能还需要根据具体的场景和需求进行进一步的评估和优化。
OpenCV实现特征检测和特征匹配⽅法汇总⽬录1.SURF2.SIFT3.ORB4.FAST5.Harris⾓点⼀幅图像中总存在着其独特的像素点,这些点我们可以认为就是这幅图像的特征,成为特征点。
计算机视觉领域中的很重要的图像特征匹配就是⼀特征点为基础⽽进⾏的,所以,如何定义和找出⼀幅图像中的特征点就⾮常重要。
这篇⽂章我总结了视觉领域最常⽤的⼏种特征点以及特征匹配的⽅法。
在计算机视觉领域,兴趣点(也称关键点或特征点)的概念已经得到了⼴泛的应⽤,包括⽬标识别、图像配准、视觉跟踪、三维重建等。
这个概念的原理是,从图像中选取某些特征点并对图像进⾏局部分析,⽽⾮观察整幅图像。
只要图像中有⾜够多可检测的兴趣点,并且这些兴趣点各不相同且特征稳定,能被精确地定位,上述⽅法就⼗分有效。
以下是实验⽤的图像:第⼀幅是⼿机抓拍的风景图,第⼆幅是遥感图像。
1.SURF特征检测的视觉不变性是⼀个⾮常重要的概念。
但是要解决尺度不变性问题,难度相当⼤。
为解决这⼀问题,计算机视觉界引⼊了尺度不变特征的概念。
它的理念是,不仅在任何尺度下拍摄的物体都能检测到⼀致的关键点,⽽且每个被检测的特征点都对应⼀个尺度因⼦。
理想情况下,对于两幅图像中不同尺度的的同⼀个物体点,计算得到的两个尺度因⼦之间的⽐率应该等于图像尺度的⽐率。
近⼏年,⼈们提出了多种尺度不变特征,本节介绍其中的⼀种:SURF特征。
SURF全称为“加速稳健特征”(Speeded Up Robust Feature),我们将会看到,它们不仅是尺度不变特征,⽽且是具有较⾼计算效率的特征。
我们⾸先进⾏常规的特征提取和特征点匹配,看看效果如何。
#include "highgui/highgui.hpp"#include "opencv2/nonfree/nonfree.hpp"#include "opencv2/legacy/legacy.hpp"#include <iostream>using namespace cv;using namespace std;int main(){Mat image01 = imread("2.jpg", 1); //右图Mat image02 = imread("1.jpg", 1); //左图namedWindow("p2", 0);namedWindow("p1", 0);imshow("p2", image01);imshow("p1", image02);//灰度图转换Mat image1, image2;cvtColor(image01, image1, CV_RGB2GRAY);cvtColor(image02, image2, CV_RGB2GRAY);//提取特征点SurfFeatureDetector surfDetector(800); // 海塞矩阵阈值,在这⾥调整精度,值越⼤点越少,越精准 vector<KeyPoint> keyPoint1, keyPoint2;surfDetector.detect(image1, keyPoint1);surfDetector.detect(image2, keyPoint2);//特征点描述,为下边的特征点匹配做准备SurfDescriptorExtractor SurfDescriptor;Mat imageDesc1, imageDesc2;pute(image1, keyPoint1, imageDesc1);pute(image2, keyPoint2, imageDesc2);//获得匹配特征点,并提取最优配对FlannBasedMatcher matcher;vector<DMatch> matchePoints;matcher.match(imageDesc1, imageDesc2, matchePoints, Mat());cout << "total match points: " << matchePoints.size() << endl;Mat img_match;drawMatches(image01, keyPoint1, image02, keyPoint2, matchePoints, img_match);namedWindow("match", 0);imshow("match",img_match);imwrite("match.jpg", img_match);waitKey();return 0;}由上⾯的特征点匹配的效果来看,匹配的效果还是相当糟糕的,如果我们拿着这样⼦的匹配结果去实现图像拼接或者物体追踪,效果肯定是极差的。
OpenCV特征提取与图像检索实现(附代码)“拍立淘”“一键识花”“街景匹配”……不知道大家在使用这些神奇的功能的时候,有没有好奇过它们背后的技术原理?其实这些技术都离不开最基本的图像检索技术。
本篇文章我们就将对这一技术的原理进行介绍,并通过一个简单的Python脚本来实现一个最基本的图像检索demo。
▌图像特征首先我们需要明白图像特征是什么以及它的使用方法。
图像特征是一种简单的图像模式,基于这种模式我们可以描述我们在图像上所看到的内容。
例如,在一张跟猫有关的图片中,猫咪的眼睛就可以作为这幅图像的特征。
特征在(包括但不限于)计算机视觉中的主要作用是将视觉信息转换为向量空间表示。
这种向量空间表示让我们可以利用数学运算对其进行处理,例如通过计算寻找相似向量(这可以用来寻找相似图像或图像中的相似目标)。
▌如何从图像中获取特征?从图像中获取特征的方法有两种,第一种是通过提取图像描述符实现(白盒算法);第二种通过基于神经网络的方法实现(黑盒算法)。
本文主要介绍第一种方法。
特征提取的算法有很多,最常用的有:SURF、ORB、SIFT、BRIEF等。
这些算法大多是基于图像梯度的。
为了简化安装需求,本教程使用的是KAZE描述符,因为其他描述符在python的基础OpenCV库中没有提供。
下面是特征提取器的实现代码:import cv2import numpy as npimport scipyfrom scipy.misc import imreadimport cPickle as pickleimport randomimport osimport matplotlib.pyplot as plt# Feature extractor# 特征提取器def extract_features(image_path, vector_size=32): image = imread(image_path, mode='RGB')try:# Using KAZE, cause SIFT, ORB and other was moved to additional module# which is adding addtional pain during install#此处为了简化安装步骤,使用KAZE,因为SIFT/ORB以及其他特征算子需要安#装额外的模块alg = cv2.KAZE_create()# Finding image keypoints#寻找图像关键点kps = alg.detect(image)# Getting first 32 of them.#计算前32个# Number of keypoints is varies depend on image size and color pallet#关键点的数量取决于图像大小以及彩色调色板# Sorting them based on keypoint response value(bigger is better)#根据关键点的返回值进行排序(越大越好)kps = sorted(kps, key=lambda x:-x.response)[:vector_size]# computing descriptors vector#计算描述符向量kps, dsc = pute(image, kps)# Flatten all of them in one big vector - our feature vector# 将其放在一个大的向量中,作为我们的特征向量dsc = dsc.flatten()# Making descriptor of same size# 使描述符的大小一致# Descriptor vector size is 64#描述符向量的大小为64needed_size = (vector_size * 64)if dsc.size# if we have less the 32 descriptors then just adding zeros# at the end of our feature vector#如果少于32个描述符,则在特征向量后面补零dsc = np.concatenate([dsc,np.zeros(needed_size - dsc.size)])except cv2.error as e:print 'Error: ', ereturn None return dscdef batch_extractor(images_path,pickled_db_path='features.pck'):files = [os.path.join(images_path, p) for p insorted(os.listdir(images_path))]result = {}for f in files:print 'Extracting features from image %s' % fname = f.split('/')[-1].lower()result[name] = extract_features(f)# saving all our feature vectors in pickled file# 将特征向量存于pickled 文件with open(pickled_db_path, 'w') as fp:pickle.dump(result, fp)OpenCV中的大多数特征提取算法的python接口都相同,所以如果你想要使用SIFT特征,只需要用SIFT_create替换KAZE_create就行。
特征点检测与匹配算法引言特征点检测与匹配算法是计算机视觉领域的重要研究方向之一。
它在图像处理、图像识别、目标跟踪等应用中发挥着重要的作用。
本文将从特征点检测的概念出发,逐步介绍特征点检测与匹配算法的原理、常用方法及其应用。
特征点检测概述特征点是图像中具有显著性、稳定性且可重复检测的图像区域。
特征点检测是指在图像中自动寻找这些具有特征性的点,并进行描述和匹配的过程。
特征点检测广泛应用于图像匹配、图像拼接、目标识别等领域。
特征点检测算法原理Harris角点检测算法Harris角点检测算法是一种经典的特征点检测算法。
它通过计算图像中每个像素点的Harris响应函数来判断其是否为角点。
Harris角点检测算法对图像的局部对比度和灰度变化进行了建模,能够检测出图像中的角点。
算法步骤: 1. 计算图像的灰度梯度。
2. 对每个像素计算一个自相关矩阵。
3. 计算自相关矩阵的Harris响应函数。
4. 设置一个阈值,根据Harris响应函数的值判断是否为角点。
SIFT算法尺度不变特征转换(SIFT)算法是一种常用的特征点检测算法。
SIFT算法通过使用高斯差分函数来检测图像中的关键点,并计算关键点的描述子,实现了对旋转、尺度缩放等变换的不变性。
算法步骤: 1. 构建高斯金字塔。
2. 在金字塔的每一层上使用高斯差分函数寻找关键点。
3. 基于关键点的位置和尺度,生成关键点的描述子。
4. 使用描述子进行关键点的匹配。
SURF算法加速稳健特征(SURF)算法是一种基于SIFT算法的改进方法。
SURF算法通过加速计算和改进特征描述子的方式,提高了特征点检测的效率和稳定性。
算法步骤: 1. 使用高斯滤波器构建图像金字塔。
2. 使用盒子滤波器计算图像的Hessian矩阵。
3. 使用Hessian矩阵检测图像中的极值点作为特征点。
4. 根据特征点的尺度和方向计算特征点的描述子。
特征点匹配算法特征点匹配是指在两幅图像之间寻找相同或相似的特征点的过程。
OpenCV成长之路(9):特征点检测与图像匹配特征点检测与图像匹配称兴趣点、关键点,它是在图像中突出且具有代表意义的一些点,通过这些点我们可以用来识别图像、进行图像配准、进行3D重建等。
本文主要介绍OpenCV中几种定位与表示关键点的函数。
一、Harris角点角点是图像中最基本的一种关键点,它是由图像中一些几何结构的关节点构成,很多都是线条之间产生的交点。
Harris 角点是一类比较经典的角点类型,它的基本原理是计算图像中每点与周围点变化率的平均值。
(1)(2)其中I(x+u,y+u)代表了点(x,y)邻域点的灰度值。
通过变换可以将上式变化为一个协方差矩阵求特征值的问题(2),具体数学原理本文不过多描述。
OpenCV的Hairrs角点检测的函数为cornerHairrs(),但是它的输出是一幅浮点值图像,浮点值越高,表明越可能是特征角点,我们需要对图像进行阈值化。
我们使用一张建筑图像来显示:int main() { Mat image=imread("../buliding.png"); Mat gray; cvtColor(image,gray,CV_BGR2GRAY);Mat cornerStrength;cornerHarris(gray,cornerStrength,3,3,0.01);threshold(cornerStrength,cornerStrength,0.001,255,THRESH_B INARY); return 0; } 首先我们来说明一下cornerHairrs()这个函数参数的意思:前2参数是输入与输出,输入是一个灰度图像,输出是一个浮点图像,第三个参数指定角点分析的邻域,第4个参数实际上在角点求取过程中计算梯度图像的核窗口大小,第5个参数是它原理公式(2)中的一个系数。
从上面的例子的结果我们可以看到,有很多角点都是粘连在一起的,我们下面通过加入非极大值抑制来进一步去除一些粘在一起的角点。
非极大值抑制原理是,在一个窗口内,如果有多个角点则用值最大的那个角点,其他的角点都删除,窗口大小这里我们用3*3,程序中通过图像的膨胀运算来达到检测极大值的目的,因为默认参数的膨胀运算就是用窗口内的最大值替代当前的灰度值。
程序的最后使用了一个画角点的函数将角点显示在图像中,这个函数与本系列第5篇中画角点的函数是一致的。
int main() { Mat image=imread("../buliding.png");Mat gray; cvtColor(image,gray,CV_BGR2GRAY);Mat cornerStrength;cornerHarris(gray,cornerStrength,3,3,0.01); double maxStrength; double minStrength; // 找到图像中的最大、最小值minMaxLoc(cornerStrength,&minStrength,&maxStre ngth); Mat dilated; Mat locaMax; // 膨胀图像,最找出图像中全部的局部最大值点dilate(cornerStrength,dilated,Mat()); // compare是一个逻辑比较函数,返回两幅图像中对应点相同的二值图像compare(cornerStrength,dilated,locaMax,CMP_EQ);Mat cornerMap; double qualityLevel=0.01; double th=qualityLevel*maxStrength; // 阈值计算threshold(cornerStrength,cornerMap,th,255,THRESH_BINARY ); cornerMap.convertTo(cornerMap,CV_8U); //逐点的位运算bitwise_and(cornerMap,locaMax,cornerMap); drawCornerOnImage(image,cornerMap);namedWindow("result"); imshow("result",image); waitKey(); return 0; } void drawCornerOnImage(Mat& image,const Mat&binary){ Mat_<uchar>::const_iteratorit=binary.begin<uchar>();Mat_<uchar>::const_iteratoritd=binary.end<uchar>(); for(inti=0;it!=itd;it++,i++) { if(*it)circle(image,Point(i%image.cols,i/image.cols),3,Scalar(0,255,0) ,1); } } 现在我们得到的效果就比默认的函数得到的结果有相当的改善。
由于cornerHarris的一些缺点,OpenCV提供了另一个相似的函数GoodFeaturesToTrack()它用角点间的距离限制来防止角点粘连在一起。
goodFeaturesToTrack(image,corner,500, // 最多检测到的角点数0.01, // 阈值系数10); // 角点间的最小距离它可以得到与上面基本一致的结果。
二、FAST特征点harris特征在算法复杂性上比较高,在大的复杂的目标识别或匹配应用上效率不能满足要求,OpenCV提供了一个快速检测角点的类FastFeatureDetector,而实际上FAST并不是快的意思,而是Features from Accelerated Segment Test,但这个算法效率确实比较高,下面我们来看看这个类的用法。
OpenCV里为角点检测提供了统一的接口,通过类下面的detect方法来检测对应的角点,而输出格式都是vector<KeyPoint>。
vector<KeyPoint> keypoints; FastFeatureDetector fast( // 定义检测类40); //40是检测的阈值fast.detect(image,keypoints);drawKeypoints(image,keypoints,image,Scalar(255,0,0), DrawMatchesFlags::DRAW_OVER_OUTIMG); 其中drawKeypoints是OpenCV提供的在图像上画角点的函数。
它的参数可以让我们选择用不同的方式标记出特征点。
三、尺度不变的SURF特征surf特征是类似于SIFT特征的一种尺度不变的特征点,它的优点在于比SIFT效率要高,在实际运算中可以达到实时性的要求,关于SURF的原理这里就不过多的介绍,网络上这类的文章很多。
类似于FAST特征点的求法,SURF也可以使用通用接口求得,而SURF特征的类为SurfFeatureDetector,类似的SIFT 特征点的检测类为SiftFeatureDetector。
#include <opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> #include<opencv2/nonfree/features2d.hpp> using namespacecv; int main() { Matimage=imread("../buliding.png");vector<KeyPoint> keypoints;SurfFeatureDetector surf(2500.);surf.detect(image,keypoints);drawKeypoints(image,keypoints,image,Scalar(255,0,0), DrawMatchesFlags::DRAW_RICH_KEYPOINTS); namedWindow("result"); imshow("result",image); waitKey(); return 0; } 这里有一个值得说明的问题是:OpenCV2.4版本后好像把SurfFeatureDetector这个类的定义移到了头文件nonfree/features2d.hpp中,所以头文件中要加入该文件,并且要把opencv_nonfree24xd.lib加入属性表的链接器熟悉的输入中,其中x换成你当前opencv的版本号。
最终的显示效果如下:四、SURF特征的描述在图像配准中,特征点的描述往往不是位置这么简单,而是使用了一个N维向量来描述一个特征点,这些描述子之间可以通过定义距离公式来比较相近程度。
SurfDescriptorExtractor 是一个提取SURF特征点以及其描述的类。
下面是一个宽景图像的拼接配准的例子:#include <opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> #include<opencv2/nonfree/features2d.hpp> #include<opencv2/legacy/legacy.hpp> using namespace cv; int main() { Mat image1=imread("../b1.png");Mat image2=imread("../b2.png"); // 检测surf特征点vector<KeyPoint> keypoints1,keypoints2; SurfFeatureDetector detector(400);detector.detect(image1, keypoints1);detector.detect(image2, keypoints2); // 描述surf特征点SurfDescriptorExtractor surfDesc; Matdescriptros1,descriptros2;pute(image1,keypoints1,descriptros1); pute(image2,keypoints2,descriptros2); // 计算匹配点数BruteForceMatcher<L2<float>>matcher;vector<DMatch> matches;matcher.match(descriptros1,descriptros2,matches);std::nth_element(matches.begin(),matches.begin()+24,matches.e nd()); matches.erase(matches.begin()+25,matches.end()); // 画出匹配图Mat imageMatches;drawMatches(image1,keypoints1,image2,keypoints2,matches, imageMatches,Scalar(255,0,0));namedWindow("image2"); imshow("image2",image2); waitKey(); return 0; } 程序中我们选择了25个配准点,得到最后的匹配如下:。