【OpenCV教程】特性工程

打印 上一主题 下一主题

主题 528|帖子 528|积分 1584

@
目次

1.模板匹配

1.1 原理

模板图像在原图像上从原点开始移动,盘算模板与原图被模板覆盖的地方的差别程度,盘算方法有几种,然后将每次盘算的效果放进输出矩阵。若原图像为A*B大小,模板为a*b大小,则 输出矩阵为(A-a+1)*(B-b+1) 大小。
1.2 API
  1. CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ,
  2.                                  OutputArray result, int method, InputArray mask = noArray() );
复制代码

  • 参数如下
参数含义image输入图像,数据范例Mattempl(template)模板图像,数据范例Matresult输出矩阵,深度为CV_32FC1。若原图像为A*B大小,模板为a*b大小,则 输出矩阵为(A-a+1)*(B-b+1) 大小。method模板匹配盘算方法。详见下文mask掩码图像。其大小与模板图像必须相同,且必须为灰度图。匹配时,对于掩码中的非0像素匹配算法起作用,掩码中的灰度值为0的像素位置,匹配算法不起作用。1.3 模板匹配盘算方法
  1. enum TemplateMatchModes {
  2.     TM_SQDIFF        = 0,
  3.     TM_SQDIFF_NORMED = 1,
  4.     TM_CCORR         = 2,
  5.     TM_CCORR_NORMED  = 3,
  6.     TM_CCOEFF        = 4,
  7.     TM_CCOEFF_NORMED = 5
  8. };
复制代码

  • method可选值如下
method可选值含义式子TM_SQDIFF盘算平方误差,盘算出来的值越小,则匹配得越好$R_{sq_diff}=\sum_{x{\prime},y{\prime}}\left[T(x{\prime},y)-I(x+x{\prime},y+y) \right]^2$TM_SQDIFF_NORMED盘算归一化平方误差,盘算出来的值越接近0,则匹配得越好$R_{sq_diff_normed}=\frac{\sum_{x{\prime},y{\prime}}\left[T(x{\prime},y)-I(x+x{\prime},y+y) \right]2}{\sqrt{\sum_{x,y{\prime}}T(x,y{\prime})2 \cdot \sum_{x{\prime},y{\prime}}I(x+x{\prime},y+y)^2 }}$TM_CCORR盘算相关性,盘算出来的值越大,则匹配得越好$R_{ccorr}=\sum_{x{\prime},y{\prime}}T(x{\prime},y) \cdot I(x+x{\prime},y+y)$TM_CCORR_NORMED盘算归一化相关性,盘算出来的值越接近1,则匹配得越好$R_{ccorr_normed}=\frac{\sum_{x{\prime},y{\prime}} T(x{\prime},y) \cdot I(x+x{\prime},y+y)  }{\sqrt{\sum_{x{\prime},y{\prime}}T(x{\prime},y)^2 \cdot \sum_{x{\prime},y{\prime}}I(x+x{\prime},y+y)^2 }}$TM_CCOEFF盘算相关系数,盘算出来的值越大,则匹配得越好$R_{ccoff}=\sum_{x{\prime},y{\prime}}T{\prime}(x,y^{\prime}) \cdot I{\prime}(x+x,y+y^{\prime}),  \  T{\prime}(x,y{\prime})=T(x,y^{\prime}) - \frac{\sum_{x{\prime},y{\prime}} T(x{\prime\prime},y) }{w \cdot h} ,\ I{\prime}(x,y{\prime})=I(x,y^{\prime}) - \frac{\sum_{x{\prime},y{\prime}} I(x{\prime\prime},y) }{w \cdot h} $TM_CCOEFF_NORMED盘算归一化相关系数,盘算出来的值越接近1,则匹配得越好$R_{ccoeff_normed}=\frac{\sum_{x{\prime},y{\prime}} T{\prime}(x,y^{\prime}) \cdot I{\prime}(x+x,y+y^{\prime}) }{\sqrt{\sum_{x{\prime},y{\prime}}T{\prime}(x,y{\prime})2 \cdot \sum_{x{\prime},y{\prime}}I{\prime}(x+x,y+y{\prime})2 }}$1.4 掩码的使用

在进行特性匹配时,我们偶然并不必要用整个图片作为模板,由于模板的背景可能会干扰匹配的效果。因此,我们必要加入掩码,就可以屏蔽掉背景进行模板匹配
获得掩码


  • 模板图像转灰度图
  • 二值化屏蔽背景
1.5 效果
  1. Mat xuenai = imread("xuenai.jpg");
  2. imshow("xuenai",xuenai);
  3. Mat templ= imread("xuenai_rect.jpg");
  4. imshow("template",templ);
  5. Mat match_result;
  6. matchTemplate(xuenai,templ,match_result,TM_SQDIFF);
  7. Point temLoc;
  8. Point minLoc;
  9. Point maxLoc;
  10. double min,max;
  11. minMaxLoc(match_result,&min,&max,&minLoc,&maxLoc);
  12. temLoc=minLoc;
  13. rectangle(xuenai,Rect(temLoc.x,temLoc.y,templ.cols,templ.rows),Scalar(0,0,255));
  14. imshow("xuenai_match",xuenai);
  15. waitKey();
复制代码


1.5 模板匹配的缺陷

无法应对旋转
  1. Mat xuenai = imread("xuenai.jpg");
  2.         rotate(xuenai,xuenai,ROTATE_90_CLOCKWISE);
  3.         imshow("xuenai",xuenai);
  4.         Mat templ= imread("xuenai_rect.jpg");
  5.         Mat match_result;
  6.         matchTemplate(xuenai,templ,match_result,TM_SQDIFF);
  7.         Point temLoc;
  8.         Point minLoc;
  9.         Point maxLoc;
  10.         double min,max;
  11.         minMaxLoc(match_result,&min,&max,&minLoc,&maxLoc);
  12.         temLoc=minLoc;
  13.         rectangle(xuenai,Rect(temLoc.x,temLoc.y,templ.cols,templ.rows),Scalar(0,0,255));
  14.         imshow("xuenai_match",xuenai);
  15.         waitKey();
复制代码

无法应对缩放
  1. Mat xuenai = imread("xuenai.jpg");
  2. resize(xuenai,xuenai,Size(500,500));
  3. imshow("xuenai",xuenai);
  4. Mat templ= imread("xuenai_rect.jpg");
  5. Mat match_result;
  6. matchTemplate(xuenai,templ,match_result,TM_SQDIFF);
  7. Point temLoc;
  8. Point minLoc;
  9. Point maxLoc;
  10. double min,max;
  11. minMaxLoc(match_result,&min,&max,&minLoc,&maxLoc);
  12. temLoc=minLoc;
  13. rectangle(xuenai,Rect(temLoc.x,temLoc.y,templ.cols,templ.rows),Scalar(0,0,255));
  14. imshow("xuenai_match",xuenai);
  15. waitKey();
复制代码

2.cornerHarris(对灰度图)

2.1 角点的形貌


  • 一阶导数(即灰度的梯度)的局部最大所对应的像素点;
  • 两条及两条以上边缘的交点;
  • 图像中梯度值和梯度方向的变化速率都很高的点;
  • 角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。
2.2 原理(前置知识要求:线性代数)(以下为bolcksize=2的情况)

使用一个固定窗口在图像上进行任意方向上的滑动,比较滑动前与滑动后两种情况,窗口中的像素灰度变化程度,假如存在任意方向上的滑动,都有着较大灰度变化,那么我们可以认为该窗口中存在角点。
考虑到一个灰度图像 . 划动窗口  (with displacements  在x方向和  方向)  盘算像素灰度变化。
$$
E(u,v)=\sum w(x,y) \left[   I(x+u,y+v)-I(x,y)        \right]^2
$$
其中:

  • w(x,y) is the window at position (x,y)
  • I(x,y) is the intensity at (x,y)
  • I(x+u,y+v) is the intensity at the moved window (x+u,y+v)、
为了探求带角点的窗口,搜索像素灰度变化较大的窗口。于是, 我们盼望最大化以下式子:
$$
\sum_{x,y}\left[   I(x+u,y+v)-I(x,y)        \right]^2
$$
泰勒睁开:
$$
E(u,v) \approx \sum_{x,y} \left[ I(x,y) +u I_x +v I_y - I(x,y)  \right]^2
$$

  • Ix,Iy是通过sobel算子盘算的一阶导数
矩阵化:
$$
E(u,v) \approx \begin{bmatrix} u & v \end{bmatrix} \left( \sum_{x,y}  w(x,y)\begin{bmatrix} I_x^2 & I_x I_y \ I_x I_y &  I_y^2\end{bmatrix}   \right)  \begin{bmatrix} u \ v \end{bmatrix}
$$
得二次型:
$$
M=\sum_{x,y}  w(x,y)\begin{bmatrix} I_x^2 & I_x I_y \ I_x I_y &  I_y^2\end{bmatrix}
$$
因此有等式:
$$
E(u,v) \approx \begin{bmatrix} u & v \end{bmatrix} M  \begin{bmatrix} u \ v \end{bmatrix}
$$
每个窗口中盘算得到一个值。这个值决定了这个窗口中是否包罗了角点。
$$
R=\det{M}-k \cdot\text{trace}(M)^2
$$
其中,det(M) = 矩阵M的行列式,trace(M) = 矩阵M的迹

  • R为正值时,检测到的是角点,R为负时检测到的是边,R很小时检测到的是平展区域。
2.3 API
  1. CV_EXPORTS_W void cornerHarris( InputArray src, OutputArray dst, int blockSize,
  2.                                 int ksize, double k,
  3.                                 int borderType = BORDER_DEFAULT );
复制代码

  • 参数如下
参数含义src(source)输入图片(灰度图)深度要求:CV_8UC1或CV_32FC1dst(destination)输出图片,数据范例MatbolckSize检测窗口的大小,越大则对角点越敏感,一般取2ksize(kernal size)使用sobel算子盘算一阶导数时的滤波器大小,一般取3即可。k盘算用到的系数,公认一般取值在0.02~0.06。borderType界限填充方式,默认为黑边。2.4 流程


  • 转灰度图
  • 使用cornerHarris函数检测
  • 使用normalize函数归一化处理和convertScaleAbs绝对化
  • 遍历输出图像并筛选角点。不要使用迭代器的遍历方式,由于太慢!


  • 经过实测,以下这种用行数调用ptr函数的遍历方式是最快的
  1. Mat xuenai = imread("xuenai.jpg");
  2. imshow("xuenai", xuenai);
  3. //转灰度图
  4. Mat xuenai_gray(xuenai.size(),xuenai.type());
  5. cvtColor(xuenai,xuenai_gray,COLOR_BGR2GRAY);
  6. Mat xuenai_harris;
  7. cornerHarris(xuenai_gray,xuenai_harris,2,3,0.04);
  8. normalize(xuenai_harris,xuenai_harris,0,255,NORM_MINMAX,-1);
  9. convertScaleAbs(xuenai_harris,xuenai_harris);
  10. namedWindow("xuenai_harris");
  11. createTrackbar("threshold","xuenai_harris", nullptr,255);
  12. while (1) {
  13.     int thres = getTrackbarPos("threshold", "xuenai_harris");
  14.     if(thres==0)thres=100;
  15.     Mat harris_result=xuenai.clone();
  16.     for(int i=0;i<xuenai_harris.rows;i++){
  17.         uchar * ptr =xuenai_harris.ptr(i);
  18.         for(int j=0;j<xuenai_harris.cols;j++){
  19.             int value=(int) *ptr;
  20.             if(value>thres){
  21.                 circle(harris_result, Point(j,i), 3, Scalar(0, 0, 255));
  22.             }
  23.             ptr++;
  24.         }
  25.     }
  26.     imshow("xuenai_harris",harris_result);
  27.     if (waitKey(0) == 'q')break;
  28. }
复制代码

进行缩放和旋转




  • 可以看到,无论是旋转照旧缩放,关键点都保持得非常稳固。
5.FAST到OBR(对灰度图)

5.1 概述

前文已经阐述,SIFT和SURF已经做到了角点在旋转和缩放下的稳固性,但是它们还有一个致命的缺陷,就是它们难以做到实时运算,因此,FAST和OBR应运而生了。
FAST原理

从图片中选取一个坐标点P,获取该点的像素值,接下来判定该点是否为特性点.
选取一个以选取点P坐标为圆心的半径等于r的Bresenham圆(一个盘算圆的轨迹的离散算法,得到整数级的圆的轨迹点),一般来说,这个圆上有16个点,如下所示


  • p在图像中表示一个被识别为兴趣点的像素。令它的强度为 Ip;
  • 选择一个合适的阈值t;
  • 考虑被测像素四周的16个像素的圆圈。 假如这16个像素中存在一组ñ个连续的像素的像素值,比 Ip+t 大,或比 Ip−t小,则像素p是一个角点。ñ被设置为12。
  • 使用一种快速测试(high-speed test)可快速清除了大量的非角点。这个方法只检测在1、9、5、13个四个位置的像素,(起首检测1、9位置的像素与阈值比是否太亮或太暗,假如是,则检查5、13)。假如p是一个角点,则至少有3个像素比 Ip+t大或比 Ip−t暗。假如这两者都不是这样的话,那么p就不能成为一个角点。然后可以通过检查圆中的所有像素,将全部分段测试标准应用于通过的对候选的角点。这种探测器本身表现出很高的性能,但有一些缺点:
<ul>它不能拒绝n detect(xuenai_gray,xuenai_ObrKp);    Mat fast_result=xuenai_transform.clone(),obr_result=xuenai_transform.clone();    drawKeypoints(fast_result,xuenai_FastKp,fast_result,Scalar::all(-1),DrawMatchesFlags:RAW_RICH_KEYPOINTS);    drawKeypoints(obr_result,xuenai_ObrKp,obr_result,Scalar::all(-1),DrawMatchesFlags:RAW_RICH_KEYPOINTS);    imshow("fast_result",fast_result);    imshow("obr_result",obr_result);    if (waitKey(0) == 'q')break;}[/code]调整threshold



进行缩放和旋转


错误
  1. Mat xuenai = imread("xuenai.jpg");
  2. imshow("xuenai", xuenai);
  3. namedWindow("panel");
  4. createTrackbar("threshold","panel", nullptr,255);
  5. createTrackbar("angle","panel", nullptr,360);
  6. createTrackbar("width","panel", nullptr,1000);
  7. createTrackbar("height","panel", nullptr,1000);
  8. while (1) {
  9.     int thres = getTrackbarPos("threshold", "panel");
  10.     if(thres==0)thres=100;
  11.     int width = getTrackbarPos("width", "panel");
  12.     if(width==0)width=xuenai.cols;
  13.     int height = getTrackbarPos("height", "panel");
  14.     if(height==0)height=xuenai.rows;
  15.     int angle = getTrackbarPos("angle","panel");
  16.   
  17.     Mat xuenai_harris, xuenai_transform=xuenai.clone();
  18.     resize(xuenai_transform,xuenai_transform,Size(width,height));
  19.     Mat M= getRotationMatrix2D(Point2f(xuenai.cols/2,xuenai.rows/2),angle,1);
  20.     warpAffine(xuenai_transform,xuenai_transform,M,xuenai_transform.size());
  21.     Mat xuenai_gray(xuenai.size(),xuenai.type());
  22.     cvtColor(xuenai_transform,xuenai_gray,COLOR_BGR2GRAY);
  23.     cornerHarris(xuenai_gray,xuenai_harris,2,3,0.04);
  24.     normalize(xuenai_harris,xuenai_harris,0,255,NORM_MINMAX,-1);
  25.     convertScaleAbs(xuenai_harris,xuenai_harris);
  26.     Mat harris_result=xuenai_transform.clone();
  27.     for(int i=0;i<xuenai_harris.rows;i++){
  28.         uchar * ptr =xuenai_harris.ptr(i);
  29.         for(int j=0;j<xuenai_harris.cols;j++){
  30.             int value=(int) *ptr;
  31.             if(value>thres){
  32.                 circle(harris_result, Point(j,i), 3, Scalar(0, 0, 255));
  33.             }
  34.             ptr++;
  35.         }
  36.     }
  37.     imshow("xuenai_harris",harris_result);
  38.     if (waitKey(0) == 'q')break;
  39. }
复制代码
前文已经提及,FAST算法不支持形貌子的盘算
  1. CV_EXPORTS_W void goodFeaturesToTrack( InputArray image, OutputArray corners,
  2.                                      int maxCorners, double qualityLevel, double minDistance,
  3.                                      InputArray mask = noArray(), int blockSize = 3,
  4.                                      bool useHarrisDetector = false, double k = 0.04 );
  5. CV_EXPORTS_W void goodFeaturesToTrack( InputArray image, OutputArray corners,
  6.                                      int maxCorners, double qualityLevel, double minDistance,
  7.                                      InputArray mask, int blockSize,
  8.                                      int gradientSize, bool useHarrisDetector = false,
  9.                                      double k = 0.04 );
复制代码
6.Brute-Force与FLANN特性匹配

6.1 概述

Brute-Force

暴力匹配(Brute-force matcher)是最简单的二维特性点匹配方法。对于从两幅图像中提取的两个特性形貌符聚集,对第一个聚集中的每个形貌符Ri,从第二个聚集中找出与其间隔最小的形貌符Sj作为匹配点。
暴力匹配显然会导致大量错误的匹配效果,还会出现一配多的情况。通过交织匹配或设置比较阈值筛选匹配效果的方法可以改进暴力匹配的质量。

  • 假如参考图像中的形貌符Ri与检测图像中的形貌符Sj的互为最佳匹配,则称(Ri , Sj)为同等配对。交织匹配通过删除非同等配对来筛选匹配效果,可以避免出现一配多的错误。
  • 比较阈值筛选是指对于参考图像的形貌符Ri,从检测图像中找到间隔最小的形貌符Sj1和间隔次小的形貌符Sj2。设置比较阈值t∈[0.5 , 0.9],只有当最优匹配间隔与次优匹配间隔满足阈值条件d (Ri , Sj1) ⁄ d (Ri , Sj2) < t时,表明匹配形貌符Sj1具有显著性,才接受匹配效果(Ri , Sj1)。
FLANN


  • 相比于Brute-Force,FLANN的速度更快
  • 由于使用的是邻近近似值,所以精度较差
6.2 API

构造函数
  1. Mat xuenai = imread("xuenai.jpg");
  2. imshow("xuenai", xuenai);
  3. namedWindow("panel");
  4. createTrackbar("threshold","panel", nullptr,255);
  5. createTrackbar("angle","panel", nullptr,360);
  6. createTrackbar("width","panel", nullptr,1000);
  7. createTrackbar("height","panel", nullptr,1000);
  8. while (1) {
  9.     int thres = getTrackbarPos("threshold", "panel");
  10.     if(thres==0)thres=100;
  11.     int width = getTrackbarPos("width", "panel");
  12.     if(width==0)width=xuenai.cols;
  13.     int height = getTrackbarPos("height", "panel");
  14.     if(height==0)height=xuenai.rows;
  15.     int angle = getTrackbarPos("angle","panel");
  16.     Mat xuenai_transform=xuenai.clone();
  17.     resize(xuenai_transform,xuenai_transform,Size(width,height));
  18.     Mat M= getRotationMatrix2D(Point2f(xuenai.cols/2,xuenai.rows/2),angle,1);
  19.     warpAffine(xuenai_transform,xuenai_transform,M,xuenai_transform.size());
  20.     Mat xuenai_gray(xuenai.size(),xuenai.type());
  21.     cvtColor(xuenai_transform,xuenai_gray,COLOR_BGR2GRAY);
  22.     vector<Point2f>xuenai_cornersSet;
  23.     goodFeaturesToTrack(xuenai_gray,xuenai_cornersSet,0,0.1,10);
  24.     for(auto corner:xuenai_cornersSet){
  25.         circle(xuenai_transform,corner,3,Scalar(0,0,255));
  26.     }
  27.     imshow("xuenai_corners",xuenai_transform);
  28.     if (waitKey(0) == 'q')break;
  29. }
复制代码

  • 参数如下
参数含义normType盘算间隔用到的方法,默认是欧氏间隔。详见下表crossCheck是否使用交织验证,默认不使用。

  • normType可选值如下
normType可选值含义NORM_L1L1范数,曼哈顿间隔NORM_L2L2范数,欧氏间隔NORM_HAMMING汉明间隔NORM_HAMMING2汉明间隔2,对每2个比特相加处理。

  • NORM_L1、NORM_L2实用于SIFT和SURF检测算法
  • NORM_HAMMING、NORM_HAMMING2实用于OBR算法
形貌子匹配

匹配方式一
  1. CV_WRAP static Ptr<SIFT> SIFT::create(int nfeatures = 0, int nOctaveLayers = 3,
  2.         double contrastThreshold = 0.04, double edgeThreshold = 10,
  3.         double sigma = 1.6);
  4.   
  5. CV_WRAP static Ptr<SIFT> SIFT::create(int nfeatures, int nOctaveLayers,
  6.     double contrastThreshold, double edgeThreshold,
  7.     double sigma, int descriptorType);
  8.   
  9. CV_WRAP static Ptr<SURF> SURF::create(double hessianThreshold=100,
  10.               int nOctaves = 4, int nOctaveLayers = 3,
  11.               bool extended = false, bool upright = false);
复制代码

  • 参数如下
参数含义queryDescriptors形貌子的查询点集,数据范例Mat,即参考图像的特性形貌符的聚集。trainDescriptors形貌子的训练点集,数据范例Mat,即检测图像的特性形貌符的聚集。matches匹配效果,长度为成功匹配的数量。mask掩码图像。其大小与输入图像必须相同,且必须为灰度图。盘算时,对于掩码中的非0像素算法起作用,掩码中的灰度值为0的像素位置,算法不起作用。

  • 特别注意和区分哪个是查询集,哪个是训练集
匹配方式二
  1. CV_WRAP virtual void Feature2D::detect( InputArray image,
  2.                                  CV_OUT std::vector<KeyPoint>& keypoints,
  3.                                  InputArray mask=noArray() );
  4.                            
  5. CV_WRAP virtual void Feature2D::detect( InputArrayOfArrays images,
  6.                      CV_OUT std::vector<std::vector<KeyPoint> >& keypoints,
  7.                      InputArrayOfArrays masks=noArray() );
复制代码

  • 参数如下
参数含义queryDescriptors形貌子的查询点集,数据范例Mat,即参考图像的特性形貌符的聚集。trainDescriptors形貌子的训练点集,数据范例Mat,即检测图像的特性形貌符的聚集。matchesvector范例,对每个特性点返回k个最优的匹配效果k返回匹配点的数量mask掩码图像。其大小与输入图像必须相同,且必须为灰度图。盘算时,对于掩码中的非0像素算法起作用,掩码中的灰度值为0的像素位置,算法不起作用。

  • 特别注意和区分哪个是查询集,哪个是训练集
Brute-Force与FLANN对输入形貌子的要求


  • Brute-Force要求输入的形貌子必须是CV_8U或者CV_32S
  • FLANN要求输入的形貌子必须是CV_32F
drawMatches绘制匹配效果
  1. CV_WRAP virtual void Feature2D::compute( InputArray image,
  2.                                   CV_OUT CV_IN_OUT std::vector<KeyPoint>& keypoints,
  3.                                   OutputArray descriptors );
  4. CV_WRAP virtual void Feature2D::compute( InputArrayOfArrays images,
  5.                       CV_OUT CV_IN_OUT std::vector<std::vector<KeyPoint> >& keypoints,
  6.                       OutputArrayOfArrays descriptors );
  7. CV_WRAP virtual void Feature2D::detectAndCompute( InputArray image, InputArray mask,
  8.                                        CV_OUT std::vector<KeyPoint>& keypoints,
  9.                                        OutputArray descriptors,
  10.                                        bool useProvidedKeypoints=false );
复制代码

  • 参数如下
参数含义img1(image1)源图像1,数据范例Matkeypoints1源图像1的关键点img2(image2)源图像2,数据范例Matkeypoints2源图像2的关键点matches1to2源图像1的形貌子匹配源图像2的形貌子的匹配效果outImg(out image)输出图像,数据范例MatmatchColor匹配的颜色(特性点和连线),默认Scalar::all(-1),颜色随机singlePointColor单个点的颜色,即未配对的特性点,默认Scalar::all(-1),颜色随机matchesMask掩码,决定哪些点将被画出,若为空,则画出所有匹配点flags特性点的绘制模式,其实就是设置特性点的那些信息必要绘制,那些不必要绘制。6.3 流程


  • 实例化BFMatcher对象
  • 根据必要,调用match函数或knnMatch函数,进行特性匹配
  • 调用drawMatches函数呈现原图,并且绘制匹配点
6.4 效果
  1. CV_EXPORTS_W void drawKeypoints( InputArray image, const std::vector<KeyPoint>& keypoints, InputOutputArray outImage,
  2.                                const Scalar& color=Scalar::all(-1), DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT );
  3. enum struct DrawMatchesFlags
  4. {
  5.   DEFAULT = 0, //!< Output image matrix will be created (Mat::create),
  6.                //!< i.e. existing memory of output image may be reused.
  7.                //!< Two source image, matches and single keypoints will be drawn.
  8.                //!< For each keypoint only the center point will be drawn (without
  9.                //!< the circle around keypoint with keypoint size and orientation).
  10.   DRAW_OVER_OUTIMG = 1, //!< Output image matrix will not be created (Mat::create).
  11.                         //!< Matches will be drawn on existing content of output image.
  12.   NOT_DRAW_SINGLE_POINTS = 2, //!< Single keypoints will not be drawn.
  13.   DRAW_RICH_KEYPOINTS = 4 //!< For each keypoint the circle around keypoint with keypoint size and
  14.                           //!< orientation will be drawn.
  15. };
复制代码

本文由博客一文多发平台 OpenWrite 发布!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

水军大提督

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表