[转]opencv学习资料

转自:http://blog.csdn.net/poem_qianmo/article/details/20537737

1:Mat imread(const string& filename, intflags=1 ); 

  eg: 

  1. Mat image0=imread("dota.jpg",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);//载入最真实的图像  
  2. ge1=imread("dota.jpg",0);//载入灰度图  
  3. Mat image2=imread("dota.jpg",199);//载入3通道的彩色图像  
  4. Mat logo=imread("dota_logo.jpg");//载入3通道的彩色图像  
************************************************************************************************************************************
2:int createTrackbar(conststring& trackbarname, conststring& winname, int* value, int count, TrackbarCallback onChange=0,void* user                       data=0);
    注释:
  • 第一个参数,const string&类型的trackbarname,表示轨迹条的名字,用来代表我们创建的轨迹条。
  • 第二个参数,const string&类型的winname,填窗口的名字,表示这个轨迹条会依附到哪个窗口上,即对应namedWindow()创建窗口时填的某一个窗口名。
  • 第三个参数,int* 类型的value,一个指向整型的指针,表示滑块的位置。并且在创建时,滑块的初始位置就是该变量当前的值。
  • 第四个参数,int类型的count,表示滑块可以达到的最大位置的值。PS:滑块最小的位置的值始终为0。
  • 第五个参数,TrackbarCallback类型的onChange,首先注意他有默认值0。这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。并且这个函数的原型必须为void XXXX(int,void*);其中第一个参数是轨迹条的位置,第二个参数是用户数据(看下面的第六个参数)。如果回调是NULL指针,表示没有回调函数的调用,仅第三个参数value有变化。
  • 第六个参数,void*类型的userdata,他也有默认值0。这个参数是用户传给回调函数的数据,用来处理轨迹条事件。如果使用的第三个参数value实参是全局变量的话,完全可以不去管这个userdata参数。
  • ******************************************************************************************************************************
3. openCV中size类型剖析
  1. Size(5, 5);//构造出的Size宽度和高度都为5,即XXX.width和XXX.height都为5  
4. 滤波
   1:方波滤波
    void boxFilter(InputArray src,OutputArray dst, int ddepth, Size ksize, Point anchor=Point(-1,-1), boolnormalize=true,
                   int borderTy   pe=BORDER_DEFAULT ) 
    

       参数详解:

  • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。该函数对通道是独立处理的,且可以处理任意通道数的图片,但需要注意,待处理的图片深度应该为CV_8U, CV_16U, CV_16S, CV_32F 以及 CV_64F之一。
  • 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。
  • 第三个参数,int类型的ddepth,输出图像的深度,-1代表使用原图深度,即src.depth()。
  • 第四个参数,Size类型(对Size类型稍后有讲解)的ksize,内核的大小。一般这样写Size( w,h )来表示内核的大小( 其中,w 为像素宽度, h为像素高度)。Size(3,3)就表示3x3的核大小,Size(5,5)就表示5x5的核大小
  • 第五个参数,Point类型的anchor,表示锚点(即被平滑的那个点),注意他有默认值Point(-1,-1)。如果这个点坐标是负值的话,就表示取核的中心为锚点,所以默认值Point(-1,-1)表示这个锚点在核的中心。
  • 第六个参数,bool类型的normalize,默认值为true,一个标识符,表示内核是否被其区域归一化(normalized)了。
  • 第七个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT,我们一般不去管它
   2:均值滤波
      void blur(InputArray src, OutputArraydst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT )  
      
  • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。该函数对通道是独立处理的,且可以处理任意通道数的图片,但需要注意,待处理的图片深度应该为CV_8U, CV_16U, CV_16S, CV_32F 以及 CV_64F之一。
  • 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。比如可以用Mat::Clone,以源图片为模板,来初始化得到如假包换的目标图。
  • 第三个参数,Size类型(对Size类型稍后有讲解)的ksize,内核的大小。一般这样写Size( w,h )来表示内核的大小( 其中,w 为像素宽度, h为像素高度)。Size(3,3)就表示3x3的核大小,Size(5,5)就表示5x5的核大小
  • 第四个参数,Point类型的anchor,表示锚点(即被平滑的那个点),注意他有默认值Point(-1,-1)。如果这个点坐标是负值的话,就表示取核的中心为锚点,所以默认值Point(-1,-1)表示这个锚点在核的中心。
  • 第五个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT,我们一般不去管它
    3: 高斯滤波
          void GaussianBlur(InputArray src,OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, intborderType=BORDER_DEFAULT )  
      
  • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。它可以是单独的任意通道数的图片,但需要注意,图片深度应该为CV_8U,CV_16U, CV_16S, CV_32F 以及 CV_64F之一。
  • 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。比如可以用Mat::Clone,以源图片为模板,来初始化得到如假包换的目标图。
  • 第三个参数,Size类型的ksize高斯内核的大小。其中ksize.width和ksize.height可以不同,但他们都必须为正数和奇数。或者,它们可以是零的,它们都是由sigma计算而来。
  • 第四个参数,double类型的sigmaX,表示高斯核函数在X方向的的标准偏差。
  • 第五个参数,double类型的sigmaY,表示高斯核函数在Y方向的的标准偏差。若sigmaY为零,就将它设为sigmaX,如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height计算出来。
  • 为了结果的正确性着想,最好是把第三个参数Size,第四个参数sigmaX和第五个参数sigmaY全部指定到。
  • 第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT,我们一般不去管它。
    4:中值滤波
        void medianBlur(InputArray src,OutputArray dst, int ksize) 
    且对于多通道图片,每一个通道都单独进行处理,并且支持就地操作(In-placeoperation)。
       

       参数详解:

  • 第一个参数,InputArray类型的src,函数的输入参数,填1、3或者4通道的Mat类型的图像;当ksize为3或者5的时候,图像深度需为CV_8U,CV_16U,或CV_32F其中之一,而对于较大孔径尺寸的图片,它只能是CV_8U。
  • 第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。我们可以用Mat::Clone,以源图片为模板,来初始化得到如假包换的目标图。
  • 第三个参数,int类型的ksize,孔径的线性尺寸(aperture linear size),注意这个参数必须是大于1的奇数,比如:3,5,7,9 ...
     5:双边滤波
                     void bilateralFilter(InputArray src, OutputArraydst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT)
  • 第一个参数,InputArray类型的src,输入图像,即源图像,需要为8位或者浮点型单通道、三通道的图像。
  • 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。
  • 第三个参数,int类型的d,表示在过滤过程中每个像素邻域的直径。如果这个值我们设其为非正数,那么OpenCV会从第五个参数sigmaSpace来计算出它来。
  • 第四个参数,double类型的sigmaColor,颜色空间滤波器的sigma值。这个参数的值越大,就表明该像素邻域内有更宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
  • 第五个参数,double类型的sigmaSpace坐标空间中滤波器的sigma值,坐标空间的标注方差。他的数值越大,意味着越远的像素会相互影响,从而使更大的区域足够相似的颜色获取相同的颜色。当d>0,d指定了邻域大小且与sigmaSpace无关。否则,d正比于sigmaSpace。
  • 第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。
**************************************************************************************************************************************************************************************** 
   6:腐蚀与膨胀
      而我们图像处理中指的形态学,往往表示的是数学形态学。
      其基本的运算包括:二值腐蚀和膨胀、二值开闭运算、骨架抽取、极限腐蚀、击中击不中变换、形态学梯度、Top-hat变换、颗粒分析、流域变换、灰值腐蚀和膨胀、灰值       开闭运算、灰值形态学梯度等。
      形态学操作就是基于形状的一系列图像处理操作。OpenCV为进行图像的形态学变换提供了快捷、方便的函数。最基本的形态学操作有二种,他们是:膨胀与腐蚀(Dilation       与Erosion)。
      在进行腐蚀和膨胀的讲解之前,首先需要注意,腐蚀和膨胀是对白色部分(高亮部分)而言的,不是黑色部分。膨胀就是图像中的高亮部分进行膨胀,“领域扩张”,效果       图拥有比原图更大的高亮区域。腐蚀就是原图中的高亮部分被腐蚀,“领域被蚕食”,效果图拥有比原图更小的高亮区域。

      膨胀与腐蚀能实现多种多样的功能,主要如下:

  • 消除噪声
  • 分割(isolate)出独立的图像元素,在图像中连接(join)相邻的元素。
  • 寻找图像中的明显的极大值区域或极小值区域
  • 求出图像的梯度
      其实,膨胀就是求局部最大值的操作。
      腐蚀是求最小值得操作。
      1:形态学膨胀
  1. C++: void dilate(  
  2.     InputArray src,  
  3.     OutputArray dst,  
  4.     InputArray kernel,  
  5.     Point anchor=Point(-1,-1),  
  6.     int iterations=1,  
  7.     int borderType=BORDER_CONSTANT,  
  8.     const Scalar& borderValue=morphologyDefaultBorderValue()   
  9. ); 
 
************************************************************************************************************************************
     根据图像处理的原理我们知道,二阶导数可以用来进行检测边缘 。 因为图像是 “二维”, 我们需要在两个方向进行求导。使用Laplacian算子将            会使求导过程变得简单。
         Laplacian 算子的定义: 
         Laplacian( )函数其实主要是利用sobel算子的运算。它通过加上sobel算子运算出的图像x方向和y方向上的导数,来得到我们载入图像的拉普拉            斯变换结果。
****************************************************************************************************************************************************************************************
    8:openCV图像金字塔

       那么,我们接下来一起看一看拉普拉斯金字塔的概念吧

      两者的简要区别:高斯金字塔用来向下降采样图像,而拉普拉斯金字塔则用来从金字塔底层图像中向上采样重建一个图像。
  • 对图像向上采样:pyrUp函数(图像尺寸加倍,图像首先在每个维度上扩大为原来的两倍,新增的行(偶数行)以0填充。然后给指定的滤波器进行卷积(实际上是一个在每个维度都扩大为原来两倍的过滤器)去估计“丢失”像素的近似值。)
  • 对图像向下采样:pyrDown函数
        这里的向下与向上采样,是对图像的尺寸而言的(和金字塔的方向相反),向上就是图像尺寸加倍,向下就是图像尺寸减半。而如果我们按上图中        演示的金字塔方           向来理解,金字塔向上图像其实在缩小,这样刚好是反过来了。
 
       高斯金字塔:
       高斯金字塔是通过高斯平滑和亚采样获得一些列下采样图像,也就是说第K层高斯金字塔通过平滑、亚采样就可以获得K+1层高斯图像,高斯金字塔包含了一系列低通滤波        器,其截至频率从上一层到下一层是以因子2逐渐增加,所以高斯金字塔可以跨越很大的频率范围
  8.1 :对图像的向下取样

        为了获取层级为 G_i+1 的金字塔图像,我们采用如下方法:

       <1>对图像G_i进行高斯内核卷积

       <2>将所有偶数行和列去除

       得到的图像即为G_i+1的图像,显而易见,结果图像只有原图的四分之一。通过对输入图像G_i(原始图像)不停迭代以上步骤就会得到整个金字塔。同时我们也可以看到,          向下取样会逐渐丢失图像的信息。

       以上就是对图像的向下取样操作,即缩小图像。

  8.2: 对图像的向上取样

       如果想放大图像,则需要通过向上取样操作得到,具体做法如下:

      <1>将图像在每个方向扩大为原来的两倍,新增的行和列以0填充

      <2>使用先前同样的内核(乘以4)与放大后的图像卷积,获得 “新增像素”的近似值

      得到的图像即为放大后的图像,但是与原来的图像相比会发觉比较模糊,因为在缩放的过程中已经丢失了一些信息,如果想在缩小和放大整个过程中减少信息的丢失,这些       数据形成了拉普拉斯金字塔。

      那么,我们接下来一起看一看拉普拉斯金字塔的概念吧

****************************************************************************************************************************************************************************************

 9:resize函数剖析

   void resize(InputArray src,OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR)

  • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。
  • 第二个参数,OutputArray类型的dst,输出图像,当其非零时,有着dsize(第三个参数)的尺寸,或者由src.size()计算出来。
  • 第三个参数,Size类型的dsize,输出图像的大小
  • 第四个参数,double类型的fx,沿水平轴的缩放系数,有默认值0
  • 第五个参数,double类型的fy,沿垂直轴的缩放系数,有默认值0
  • 第五个参数,double类型的fy,沿垂直轴的缩放系数,有默认值0

     resize( )为OpenCV中专职调整图像大小的函数。

     此函数将源图像精确地转换为指定尺寸的目标图像。如果源图像中设置了ROI(Region Of Interest ,感兴趣区域),那么resize( )函数会对源图像的ROI区域进行调整图        像尺寸的操作,来输出到目标图像中。若目标图像中已经设置ROI区域,不难理解resize( )将会对源图像进行尺寸调整并填充到目标图像的ROI中。

     很多时候,我们并不用考虑第二个参数dst的初始图像尺寸和类型(即直接定义一个Mat类型,不用对其初始化),因为其尺寸和类型可以由src,dsize,fx和fy这其他的几个        参数来确定。

****************************************************************************************************************************************************************************************

10:pryUp函数剖析

       pyrUp( )函数的作用是向上采样并模糊一张图像,说白了就是放大一张图片

       void pyrUp(InputArray src, OutputArraydst, const Size& dstsize=Size(), int borderType=BORDER_DEFAULT )  

  • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。
  • 第二个参数,OutputArray类型的dst,输出图像,和源图片有一样的尺寸和类型。
  • 第三个参数,const Size&类型的dstsize,输出图像的大小;有默认值Size(),即默认情况下,由Size(src.cols*2,src.rows*2)来进行计算,
  • 第四个参数,int类型的borderType,又来了,边界模式,一般我们不用去管它。
**********************************************************************************************************************************************************
   11:openCV霍夫变换
       霍夫变换(Hough Transform)是图像处理中的一种特征提取技术,该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定           形状的集合作为霍夫变换结果。霍夫变换运用两个坐标空间之间的变换将在一个空间中具有相同形状的曲线或直线映射到另一个坐标空间的一个           点上形成峰值,从而把检测任意形状的问题转化为统计峰值问题,霍夫变换在OpenCV中分为霍夫线变换和霍夫圆变换两种。
       1:霍夫线变换        
            我们知道,霍夫线变换是一种用来寻找直线的方法. 在使用霍夫线变换之前, 首先要对图像进行边缘检测的处理,也即霍夫线变换的直接输入只能是边缘二值图像.

            总结一下,OpenCV中的霍夫线变换有如下三种:

                <1>标准霍夫变换(StandardHough Transform,SHT),由HoughLines函数调用。

                <2>多尺度霍夫变换(Multi-ScaleHough Transform,MSHT),由HoughLines函数调用。

                <3>累计概率霍夫变换(ProgressiveProbabilistic Hough Transform,PPHT),由HoughLinesP函数调用。

           我们可以对图像中所有的点进行上述操作. 如果两个不同点进行上述操作后得到的曲线在平面相交, 这就意味着它们通过同一条直线。

           以上的说明表明,一般来说, 一条直线能够通过在平面  寻找交于一点的曲线数量来检测。而越多曲线交于一点也就意味着这个交点表示的直线由                            更多的点组成. 一般来说我们可以通过设置直线上点的阈值来定义多少条曲线交于一点我们才认为检测到了一条直线。

           这就是霍夫线变换要做的. 它追踪图像中每个点对应曲线间的交点. 如果交于一点的曲线的数量超过了阈值, 那么可以认为这个交点所代表的参数对在原图              像中为一条直线。

      2:houghLines函数详解

           我们可以用其来调用标准霍夫变换SHT和多尺度霍夫变换MSHT的OpenCV内建算法。

           void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0 ) 

      具体见:http://blog.csdn.net/poem_qianmo/article/details/26977557

***********************************************************************************************************************************

  12:openCV角点检测之Harris角点检测

          当前的图像处理领域,角点检测算法可归纳为三类:

        <1>基于灰度图像的角点检测

        <2>基于二值图像的角点检测

       <3>基于轮廓曲线的角点检测

       “如果某一点在任意方向的一个微小变动都会引起灰度很大的变化,那么我们就把它称之为角点“  

另外,关于角点的具体描述可以有几种:

  • 一阶导数(即灰度的梯度)的局部最大所对应的像素点;
  • 两条及两条以上边缘的交点;
  • 图像中梯度值和梯度方向的变化速率都很高的点;
  • 角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。
cornerHarris函数详解
cornerHarris 函数用于在OpenCV中运行Harris角点检测算子处理图像。cornerHarris 函数对于每一个像素(x,y)在邻域内,计算2x2梯度的协方差矩阵,接着它计算如下式子: ,即可以找出输出图中的局部最大值,即找出了角点。
函数原型:
void cornerHarris(InputArray src,OutputArray dst, int blockSize, int ksize, double k, intborderType=BORDER_DEFAULT )  
  • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可,且需为单通道8位或者浮点型图像。
  • 第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放Harris角点检测的输出结果,和源图片有一样的尺寸和类型。
  • 第三个参数,int类型的blockSize,表示邻域的大小,更多的详细信息在cornerEigenValsAndVecs()中有讲到。
  • 第四个参数,int类型的ksize,表示Sobel()算子的孔径大小。
  • 第五个参数,double类型的k,Harris参数。
  • 第六个参数,int类型的borderType,图像像素的边界模式,注意它有默认值BORDER_DEFAULT。更详细的解释,参考borderInterpolate( )函数。
double threshold(InputArray src,OutputArray dst, double thresh, double maxval, int type)  
函数Threshold( ) 对单通道数组应用固定阈值操作。该函数的典型应用是对灰度图像进行阈值操作得到二值图像。(另外,compare( )函数也可以达到此目的) 或者是去掉噪声,例如过滤很小或很大象素值的图像点。
  • 第一个参数,InputArray类型的src,输入数组,填单通道 , 8或32位浮点类型的Mat即可。
  • 第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放输出结果,且和第一个参数中的Mat变量有一样的尺寸和类型。
  • 第三个参数,double类型的thresh,阈值的具体值。
  • 第四个参数,double类型的maxval,当第五个参数阈值类型type取 CV_THRESH_BINARY 或CV_THRESH_BINARY_INV 阈值类型时的最大值.
  • 第五个参数,int类型的type,阈值类型,。threshold( )函数支持的对图像取阈值的方法由其确定,
  • http://blog.csdn.net/poem_qianmo/article/details/29356187(不是特别明白里面的一些函数)
  • ************************************************************************************************************************************************************************
13:重映射与SURF点检测
        重映射
       SURF点检测
       OpenCV中关于SURF算法的部分,常常涉及到的是SURFSurfFeatureDetectorSurfDescriptorExtractor这三个类,这一小节我们就来对他们进行人肉,挖      挖其背景,看看他们究竟是什么来头。
     
 绘制关键点的函数:drawKeypoints( )
void drawKeypoints(const Mat&image, const vector<KeyPoint>& keypoints, Mat& outImage, constScalar& color=Scalar::all(-1), 
                   int flags=DrawMatchesFlags::DEFAULT)
  • 第一个参数,const Mat&类型的src,输入图像。
  • 第二个参数,const vector<KeyPoint>&类型的keypoints,根据源图像得到的特征点,它是一个输出参数。
  • 第三个参数,Mat&类型的outImage,输出图像,其内容取决于第五个参数标识符falgs。
  • 第四个参数,const Scalar&类型的color,关键点的颜色,有默认值Scalar::all(-1)。
  • 第五个参数,int类型的flags,绘制关键点的特征标识符,有默认值DrawMatchesFlags::DEFAULT。可以在如下这个结构体中选取值。
SURF检测大致代码:
        Mat srcImage1 = imread("D:/TEST_GIT/test2/img/book1.jpg",1);
Mat srcImage2 = imread("D:/TEST_GIT/test2/img/book2.jpg",2);
//【2】定义需要用到的变量和类  
int minHessian = 400; //定义SURF中的hessian阈值特征点检测算子  
SurfFeatureDetector detector(minHessian); //定义一个SurfFeatureDetector(SURF) 特征检测类对象  
std::vector<KeyPoint> keypoints_1, keypoints_2; //vector模板类是能够存放任意类型的动态数组,能够增加和压缩数据  
//【3】调用detect函数检测出SURF特征关键点,保存在vector容器中  
detector.detect(srcImage1, keypoints_1);
detector.detect(srcImage2, keypoints_2); 
//【4】绘制特征关键点  
Mat img_keypoints_1; Mat img_keypoints_2;
drawKeypoints(srcImage1, keypoints_1, img_keypoints_1, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
drawKeypoints(srcImage2, keypoints_2, img_keypoints_2, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
//【5】显示效果图  
imshow("特征点检测效果图1", img_keypoints_1);
imshow("特征点检测效果图2", img_keypoints_2);
 
       在OpenCV中,使用SURF进行特征点描述主要是drawMatches方法和BruteForceMatcher类的运用,让我们一起来认识他们。
       
  1. C++: void drawMatches(const Mat& img1,  
  2. constvector<KeyPoint>& keypoints1,  
  3.  const Mat& img2,  
  4.  constvector<KeyPoint>& keypoints2,  
  5.  constvector<DMatch>& matches1to2,  
  6.  Mat& outImg,  
  7.  const Scalar&matchColor=Scalar::all(-1),  
  8.  const Scalar&singlePointColor=Scalar::all(-1),  
  9.  const vector<char>&matchesMask=vector<char>(),  
  10.  intflags=DrawMatchesFlags::DEFAULT )  
  drawMatches用于绘制出相匹配的两个图像的关键点
  • 第一个参数,const Mat&类型的img1,第一幅源图像。
  • 第二个参数,const vector<KeyPoint>&类型的keypoints1,根据第一幅源图像得到的特征点,它是一个输出参数。
  • 第三个参数,const Mat&类型的img2,第二幅源图像。
  • 第四个参数,const vector<KeyPoint>&类型的keypoints2,根据第二幅源图像得到的特征点,它是一个输出参数。
  • 第五个参数,matches1to2,第一幅图像到第二幅图像的匹配点,即表示每一个图1中的特征点都在图2中有一一对应的点、
  • 第六个参数,Mat&类型的outImg,输出图像,其内容取决于第五个参数标识符falgs。
  • 第七个参数,const Scalar&类型的matchColor,匹配的输出颜色,即线和关键点的颜色。它有默认值Scalar::all(-1),表示颜色是随机生成的。
  • 第八个参数,const Scalar&类型的singlePointColor,单一特征点的颜色,它也有表示随机生成颜色的默认值Scalar::all(-1)。
  • 第九个参数,matchesMask,确定哪些匹配是会绘制出来的掩膜,如果掩膜为空,表示所有匹配都进行绘制。
  • 第十个参数,int类型的flags,特征绘制的标识符,有默认值DrawMatchesFlags::DEFAULT。可以在如下这个DrawMatchesFlags结构体中选取值:

    BruteForceMatcher类源码分析

    

而我们用BruteForceMatcher类时用到最多的match方法,是它从DescriptorMatcher类那里的“拿来主义”。定义如下:

  1. //为各种描述符找到一个最佳的匹配(若掩膜为空)  
  2. CV_WRAP void match( const Mat& queryDescriptors, const Mat&trainDescriptors,  
  3.              CV_OUTvector<DMatch>& matches, const Mat& mask=Mat() ) const;

程序利用了SURF特征的特征描述办法,其操作封装在类SurfFeatureDetector中,利用类内的detect函数可以检测出SURF特征的关键点,保存在vector容器中。第二步利用SurfDescriptorExtractor类进行特征向量的相关计算。将之前的vector变量变成向量矩阵形式保存在Mat中。最后强行匹配两幅图像的特征向量,利用了类BruteForceMatcher中的函数match。

程序的核心思想是:

  • 使用 DescriptorExtractor 接口来寻找关键点对应的特征向量。detector(srcImage,keyPoints)方法
  • 使用 SurfDescriptorExtractor 以及它的函数 compute 来完成特定的计算。compute(srcImage,keyPoints, descriptor)方法
  • 使用 BruteForceMatcher 来匹配特征向量。match(descriptor1,descriptor2,matches)方法
  • 使用函数 drawMatches 来绘制检测到的匹配点.drawMatches( srcImage1, keyPoint1, srcImage2, keyPoints2, matches, imgMatches)
原文地址:https://www.cnblogs.com/K2154952/p/4780299.html