开发环境:Ubuntu 18.04 LTS + ROS Melodic + ViSP 3.3.1
文章内容主要参考ViSP官方教学文档:https://visp-doc.inria.fr/doxygen/visp-daily/tutorial_mainpage.html
本文主要介绍了如何使用ViSP实现关键特征点的检测以及匹配,文中使用了ORB特征提取算法在参考图像中寻找关键点,并采用BruteForce-Hamming算法实现关键点的匹配,即从视频中寻找到与参考图像中相匹配的关键点。本文主要参考了detection/matching中的 tutorial-matching-keypoint.cpp例程。首先要获取这个例程文件并编译它
svn export https://github.com/lagadic/visp.git/trunk/tutorial/detection/matching
cd matching/
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DVISP_DIR=$VISP_WS/visp-build
make
执行例程,查看效果
./tutorial-matching-keypoint
左图为参考图像,右图是视频中的实时图像,绿线连接的就是两幅图像中相互匹配的关键点
下面介绍一下代码实现过程
#include <visp3/gui/vpDisplayOpenCV.h>
#include <visp3/io/vpImageIo.h>
#include <visp3/io/vpVideoReader.h>
#include <visp3/vision/vpKeyPoint.h>
int main()
{
#if (VISP_HAVE_OPENCV_VERSION >= 0x020101)
vpImage<unsigned char> I;
vpVideoReader reader;
reader.setFileName("video-postcard.mp4");
reader.acquire(I);
const std::string detectorName = "ORB";//选择关键点检测算法
const std::string extractorName = "ORB";//选择特征提取算法
// Hamming distance must be used with ORB
const std::string matcherName = "BruteForce-Hamming";//选择关键点匹配算法
vpKeyPoint::vpFilterMatchingType filterType = vpKeyPoint::ratioDistanceThreshold;
vpKeyPoint keypoint(detectorName, extractorName, matcherName, filterType);//新建关键点容器
std::cout << "Reference keypoints=" << keypoint.buildReference(I) << std::endl;
vpImage<unsigned char> Idisp;
Idisp.resize(I.getHeight(), 2 * I.getWidth());//准备一个宽度为I两倍的图像用于展示结果
Idisp.insert(I, vpImagePoint(0, 0)); //左图放置参考图像
Idisp.insert(I, vpImagePoint(0, I.getWidth())); //右图放置视频实时图像
vpDisplayOpenCV d(Idisp, 0, 0, "Matching keypoints with ORB keypoints");
vpDisplay::display(Idisp);
vpDisplay::flush(Idisp);
while (!reader.end()) {
reader.acquire(I);//获取视频当前帧
Idisp.insert(I, vpImagePoint(0, I.getWidth()));//放置到右图位置
vpDisplay::display(Idisp);
vpDisplay::displayLine(Idisp, vpImagePoint(0, I.getWidth()), vpImagePoint(I.getHeight(), I.getWidth()),
vpColor::white, 2);//绘制一条白线将左右图分隔开
unsigned int nbMatch = keypoint.matchPoint(I);//计算图像I中关键点的数量
std::cout << "Matches=" << nbMatch << std::endl;
vpImagePoint iPref, iPcur;
for (unsigned int i = 0; i < nbMatch; i++) {
keypoint.getMatchedPoints(i, iPref, iPcur);//获取匹配点的坐标
vpDisplay::displayLine(Idisp, iPref, iPcur + vpImagePoint(0, I.getWidth()), vpColor::green);//将左右两图的匹配点连接起来
}
vpDisplay::flush(Idisp);
if (vpDisplay::getClick(Idisp, false))
break;
}
vpDisplay::getClick(Idisp);
#endif
return 0;
}
如果大家对于深度学习与计算机视觉领域感兴趣,希望获得更多的知识分享与最新的论文解读,欢迎关注我的个人公众号“深视”。
评论(0)
您还未登录,请登录后发表或查看评论