OpenCV基于DLCO描述子匹配

一:局部特征描述子介绍

2014年VGG发表了一篇基于凸优化的局部特征描述子学习(DLCO)的论文,OpenCV3.2以后在扩展模块中对该论文的完成了代码实现并发布了API支持,提供了基于DLCO的描述子生成支持、基于生成的描述子,可以实现图像特征匹配的对象识别。关于特征描述子学习相关的细节可以看这里:

http://www.robots.ox.ac.uk/~vgg/software/learn_desc/

提供了描述子模型,学习数据,C++版本实现的源代码下载

二:OpenCV程序演示

OpenCV中VGG的DLCO描述子生成支持下面几种

  • VGG_120 = 100,
  • VGG_80 = 101,
  • VGG_64 = 102,
  • VGG_48 = 103

默认支持输出描述子是120个向量即VGG_120。基于DLCO在OpenCV中代码实现对象检测与匹配大致分为如下几步:

1.加载图像

Mat box = imread("D:/vcprojects/images/box.png");
Mat scene = imread("D:/vcprojects/images/box_in_scene.png");
imshow("box image", box);
imshow("scene image", scene);

2.关键点检测(SURF)

Ptr<SURF> detector = SURF::create();
int minHessian = 400;
vector<KeyPoint> keypoints_1, keypoints_2;
detector->setHessianThreshold(minHessian);
detector->detect(box, keypoints_1);
detector->detect(box_scene, keypoints_2);

3.描述子生成(DLCO)

Ptr<VGG> vgg_descriptor = VGG::create();
Mat descriptors_1, descriptors_2;
vgg_descriptor->compute(box,  keypoints_1, descriptors_1);
vgg_descriptor->compute(box_scene, keypoints_2, descriptors_2);

4.特征匹配实现对象识别

// 计算匹配点
FlannBasedMatcher matcher;
std::vector< DMatch > matches;
matcher.match(descriptors_1, descriptors_2, matches);
double max_dist = 0; double min_dist = 100;

// 计算最大与最小距离
for (int i = 0; i < descriptors_1.rows; i++)
{
    double dist = matches[i].distance;
    if (dist < min_dist) min_dist = dist;
    if (dist > max_dist) max_dist = dist;
}
printf("-- Max dist : %f \n", max_dist);
printf("-- Min dist : %f \n", min_dist);

// 寻找最佳匹配,距离越小越好
std::vector< DMatch > good_matches;
for (int i = 0; i < descriptors_1.rows; i++)
{
    if (matches[i].distance <= min(2 * min_dist, 1.5))
    {
        good_matches.push_back(matches[i]);
    }
}

// 绘制最终匹配点
Mat img_matches;
drawMatches(box, keypoints_1, box_scene, keypoints_2,
    good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
    vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

//-- Localize the object
std::vector<Point2f> obj;
std::vector<Point2f> scene;
for (size_t i = 0; i < good_matches.size(); i++)
{
    //-- Get the keypoints from the good matches
    obj.push_back(keypoints_1[good_matches[i].queryIdx].pt);
    scene.push_back(keypoints_2[good_matches[i].trainIdx].pt);
}
Mat H = findHomography(obj, scene, RANSAC);

//-- Get the corners from the image_1 ( the object to be "detected" )
std::vector<Point2f> obj_corners(4);
obj_corners[0] = cvPoint(0, 0); obj_corners[1] = cvPoint(box.cols, 0);
obj_corners[2] = cvPoint(box.cols, box.rows); obj_corners[3] = cvPoint(0, box.rows);
std::vector<Point2f> scene_corners(4);
perspectiveTransform(obj_corners, scene_corners, H);

//-- Draw lines between the corners (the mapped object in the scene - image_2 )
line(img_matches, scene_corners[0] + Point2f(box.cols, 0), scene_corners[1] + Point2f(box.cols, 0), Scalar(0, 255, 0), 4);
line(img_matches, scene_corners[1] + Point2f(box.cols, 0), scene_corners[2] + Point2f(box.cols, 0), Scalar(0, 255, 0), 4);
line(img_matches, scene_corners[2] + Point2f(box.cols, 0), scene_corners[3] + Point2f(box.cols, 0), Scalar(0, 255, 0), 4);
line(img_matches, scene_corners[3] + Point2f(box.cols, 0), scene_corners[0] + Point2f(box.cols, 0), Scalar(0, 255, 0), 4);
//-- Show detected matches
imshow("Good Matches & Object detection", img_matches);

原图:

特征匹配结果

原文发布于微信公众号 - OpenCV学堂(CVSCHOOL)

原文发表时间:2018-04-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏逍遥剑客的游戏开发

基于法线的边缘检测

1703
来自专栏zingpLiu

机器学习之线性代数

  完整内容已上传到github:https://github.com/ZingP/machine-learning/tree/master/linear_al...

1961
来自专栏小鹏的专栏

opencv实现抠图(单一背景),替换背景图

下面简单图片演示一下: 提取mask: ? ===> ? 替换背景: ?  +  ? = ? python的opencv代码如下: # coding=utf-8...

1.3K10
来自专栏xingoo, 一个梦想做发明家的程序员

布线问题-分支限界法

问题描述:   印刷电路板不限区域划分成n*m个方格阵列。如下图所示 ?   精确的电路布线问题要求确定连接方格a的中点,到连接方格b的中点的最短布线方案。  ...

22410
来自专栏ATYUN订阅号

四个用于Keras的很棒的操作(含代码)

Keras是最广泛使用的深度学习框架之一。它在易于使用的同时,在性能方面也与TensorFlow,Caffe和MXNet等更复杂的库相当。除非你的应用程序需要一...

2184
来自专栏计算机视觉

Python中plt.plot图像保存有白边,CV2.polyline,fillpoly的参数问题,图像保存颜色发生异常

Python中,如果你遇到了PIL图像保存有白边,CV2.polyline,fillpoly,参数问题,图像保存颜色发生异常这几个问题,这篇文章就能够解决你的疑...

3572
来自专栏一心无二用,本人只专注于基础图像算法的实现与优化。

图像处理中任意核卷积(matlab中conv2函数)的快速实现。

     卷积其实是图像处理中最基本的操作,我们常见的一些算法比如:均值模糊、高斯模糊、锐化、Sobel、拉普拉斯、prewitt边缘检测等等一些和领域相关的算...

9728
来自专栏程序生活

数据挖掘作业第4章 算法设计第5章 程序实现第六章 实现结果

第4章 算法设计 4.1 实现方式1:欧式距离 实验原理如下图: ? 图 1 实验原理 4.1.1 步骤1:数据预处理 这一部分对应实验代码1的preproce...

2978
来自专栏人工智能

如何使用 scikit-learn 为机器学习准备文本数据

文本数据需要特殊处理,然后才能开始将其用于预测建模。

9348
来自专栏风口上的猪的文章

机器学习(2) - KNN识别MNIST

 https://github.com/s055523/MNISTTensorFlowSharp

2242

扫码关注云+社区

领取腾讯云代金券