KAZE匹配算法源码
来源:互联网 发布:怎么获取股票数据 编辑:程序博客网 时间:2024/05/20 05:54
一种改进的A-KAZE算法在图像配准中的应用
#include<iostream>//#include <opencv2/xfeatures2d.hpp>#include <opencv2/opencv.hpp>using namespace std;using namespace cv;void main(){ double start, duration_ms; cv::Mat mask1, mask2, imgshowcanny; cv::Mat imgShow1, imgShow2, imgShow3, imgShow4; // 声明并从data文件夹里读取两个rgb与深度图 cv::Mat rgb1 = cv::imread("F:/study work/Visual Odometry dev/VO_practice_2016.4/算法测试/KAZE算法/data/000030.jpg", 0); cv::Mat rgb2 = cv::imread("F:/study work/Visual Odometry dev/VO_practice_2016.4/算法测试/KAZE算法/data/000087.jpg", 0); vector< cv::KeyPoint > kp1, kp2, kp3, kp4; //关键点 mask1 = rgb1.clone(); //边缘检测 //cout << "Canny edge detection" << endl; //mask1 = Mat::zeros(rgb1.size(), CV_8UC1); //mask2 = Mat::zeros(rgb2.size(), CV_8UC1); cv::Canny(mask1, mask1, 50, 200, 3); //cv::Canny(rgb2, mask2, 50, 150, 3); cv::Mat element = getStructuringElement(MORPH_RECT, Size(3, 3)); dilate(mask1, mask1, element); cv::imwrite("F:/study work/Visual Odometry dev/VO_practice_2016.4/算法测试/KAZE算法/data/mask1.jpg", mask1); imgshowcanny = mask1.clone(); cv::resize(imgshowcanny, imgshowcanny, cv::Size(imgshowcanny.cols / 2, imgshowcanny.rows / 2)); cv::imshow("mask", imgshowcanny); //特征检测算法:AKAZE、ORB cv::Ptr<cv::AKAZE> akaze = AKAZE::create(AKAZE::DESCRIPTOR_MLDB, 0, 3, 0.001f, 4, 4, KAZE::DIFF_PM_G2); cv::Ptr<cv::ORB> orb = ORB::create(2000, 1.2f, 8, 31, 0, 2, ORB::FAST_SCORE, 31, 20); Mat descriptors_1, descriptors_2, descriptors_3, descriptors_4; start = double(getTickCount()); akaze->detectAndCompute(rgb1, mask1, kp1, descriptors_1, false); duration_ms = (double(getTickCount()) - start) * 1000 / getTickFrequency();//计时 std::cout << "It took " << duration_ms << " ms to detect features in pic1 using AKAZE." << std::endl; start = double(getTickCount()); akaze->detectAndCompute(rgb2, cv::Mat(), kp2, descriptors_2, false); duration_ms = (double(getTickCount()) - start) * 1000 / getTickFrequency();//计时 std::cout << "It took " << duration_ms << " ms to detect features in pic2 using AKAZE." << std::endl; orb->detectAndCompute(rgb1, cv::Mat(), kp3, descriptors_3, false); start = double(getTickCount()); orb->detectAndCompute(rgb1, cv::Mat(), kp3, descriptors_3, false); duration_ms = (double(getTickCount()) - start) * 1000 / getTickFrequency();//计时 std::cout << "It took " << duration_ms << " ms to detect features in pic1 using ORB." << std::endl; start = double(getTickCount()); orb->detectAndCompute(rgb2, cv::Mat(), kp4, descriptors_4, false); duration_ms = (double(getTickCount()) - start) * 1000 / getTickFrequency();//计时 std::cout << "It took " << duration_ms << " ms to detect features in pic2 using ORB." << std::endl; // 可视化, 显示特征点 cout << "Key points of two AKAZE images: " << kp1.size() << ", " << kp2.size() << endl; cout << "Key points of two ORB images: " << kp3.size() << ", " << kp4.size() << endl; cv::drawKeypoints(rgb1, kp1, imgShow1, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS); cv::drawKeypoints(rgb2, kp2, imgShow2, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS); cv::drawKeypoints(rgb1, kp3, imgShow3, cv::Scalar (0,255,0), cv::DrawMatchesFlags::DEFAULT); cv::drawKeypoints(rgb2, kp4, imgShow4, cv::Scalar::all(-1), cv::DrawMatchesFlags::DEFAULT); cv::imwrite("F:/study work/Visual Odometry dev/VO_practice_2016.4/算法测试/KAZE算法/data/akaze1.jpg", imgShow1); cv::imwrite("F:/study work/Visual Odometry dev/VO_practice_2016.4/算法测试/KAZE算法/data/akaze2.jpg", imgShow2); cv::imwrite("F:/study work/Visual Odometry dev/VO_practice_2016.4/算法测试/KAZE算法/data/ORB1.jpg", imgShow3); cv::imwrite("F:/study work/Visual Odometry dev/VO_practice_2016.4/算法测试/KAZE算法/data/ORB2.jpg", imgShow4); cv::resize(imgShow2, imgShow2, cv::Size(imgShow2.cols / 2, imgShow2.rows / 2)); cv::resize(imgShow1, imgShow1, cv::Size(imgShow1.cols / 2, imgShow1.rows / 2)); cv::resize(imgShow3, imgShow3, cv::Size(imgShow3.cols / 2, imgShow3.rows / 2)); cv::resize(imgShow4, imgShow4, cv::Size(imgShow4.cols / 2, imgShow4.rows / 2)); cv::imshow("AKAZE_keypoints2", imgShow2); cv::imshow("AKAZE_keypoints1", imgShow1); cv::imshow("ORB_keypoints2", imgShow4); cv::imshow("ORB_keypoints1", imgShow3); cv::waitKey(0); //暂停等待一个按键 //用Matcher匹配特征 : BFMatcher bf_matcher; FlannBasedMatcher flann_matcher; cv::Ptr<cv::DescriptorMatcher> knn_matcher = cv::DescriptorMatcher::create("BruteForce-Hamming"); std::vector< DMatch > flann_matches; std::vector< DMatch > bf_matches1, bf_matches2; std::vector< DMatch > knn_match; std::vector< std::vector<cv::DMatch> > knn_matches1, knn_matches2; start = double(getTickCount()); bf_matcher.match(descriptors_1, descriptors_2, bf_matches1); //flann_matcher.match(descriptors_1, descriptors_2, flann_matches); duration_ms = (double(getTickCount()) - start) * 1000 / getTickFrequency();//计时 std::cout << "It took " << duration_ms << " ms to do brutal-force-match on AKAZE features." << std::endl; start = double(getTickCount()); knn_matcher->knnMatch(descriptors_1, descriptors_2, knn_matches1, 2); duration_ms = (double(getTickCount()) - start) * 1000 / getTickFrequency();//计时 std::cout << "It took " << duration_ms << " ms to do knn-match on AKAZE features." << std::endl; start = double(getTickCount()); bf_matcher.match(descriptors_3, descriptors_4, bf_matches2); //flann_matcher.match(descriptors_1, descriptors_2, flann_matches); duration_ms = (double(getTickCount()) - start) * 1000 / getTickFrequency();//计时 std::cout << "It took " << duration_ms << " ms to do brutal-force-match on ORB features." << std::endl; start = double(getTickCount()); knn_matcher->knnMatch(descriptors_3, descriptors_4, knn_matches2, 2); duration_ms = (double(getTickCount()) - start) * 1000 / getTickFrequency();//计时 std::cout << "It took " << duration_ms << " ms to do knn-match on ORB features." << std::endl; //double maxdist = 0; double mindist = 1000; //for (int i = 0; i < descriptors_1.rows; i++) //{ // double dist = bf_matches[i].distance; // if (dist < mindist)mindist = dist; // if (dist > maxdist)maxdist = dist; //} //vector< DMatch > good_matches, inliers; //for (int i = 0; i < descriptors_1.rows; i++) //{ // if (bf_matches[i].distance < 4 * (mindist + 1)) // { // good_matches.push_back(bf_matches[i]); // } //} //用RANSAC求取单应矩阵的方式去掉不可靠的BF匹配 vector< DMatch > inliers1, inliers2; cout << "Computing homography (RANSAC)" << endl; vector<Point2f> points1(bf_matches1.size()); vector<Point2f> points2(bf_matches1.size()); vector<Point2f> points3(bf_matches2.size()); vector<Point2f> points4(bf_matches2.size()); for (size_t i = 0; i < bf_matches1.size(); i++) { points1[i] = kp1[bf_matches1[i].queryIdx].pt; points2[i] = kp2[bf_matches1[i].trainIdx].pt; } for (size_t i = 0; i < bf_matches2.size(); i++) { points3[i] = kp3[bf_matches2[i].queryIdx].pt; points4[i] = kp4[bf_matches2[i].trainIdx].pt; } //计算单应矩阵并找出inliers vector<uchar> flag1(points1.size(), 0); vector<uchar> flag2(points3.size(), 0); Mat H1 = findHomography(points1, points2, CV_RANSAC, 3.0, flag1); Mat H2 = findHomography(points3, points4, CV_RANSAC, 3.0, flag2); //cout << H << endl << endl; for (int i = 0; i < bf_matches1.size(); i++) { if (flag1[i]) { inliers1.push_back(bf_matches1[i]); } } cout << "AKAZE BF matches inliers size = " << inliers1.size() << endl; for (int i = 0; i < bf_matches2.size(); i++) { if (flag2[i]) { inliers2.push_back(bf_matches2[i]); } } cout << "ORB BF matches inliers size = " << inliers2.size() << endl; //去掉不可靠的HAMMING-KNN匹配 vector< cv::DMatch > goodMatches1; for (size_t i = 0; i < knn_matches1.size(); i++) { if (knn_matches1[i][0].distance < 0.7 * knn_matches1[i][1].distance) goodMatches1.push_back(knn_matches1[i][0]); } cout << "AKAZE good knn matches size = " << goodMatches1.size() << endl; vector< cv::DMatch > goodMatches2; for (size_t i = 0; i < knn_matches2.size(); i++) { if (knn_matches2[i][0].distance < 0.7 * knn_matches2[i][1].distance) goodMatches2.push_back(knn_matches2[i][0]); } cout << "ORB good knn matches size = " << goodMatches2.size() << endl; // 可视化:显示匹配的特征 cv::Mat AKAZE_BF_imgMatches; cv::Mat AKAZE_KNN_imgMatches; cv::Mat ORB_BF_imgMatches; cv::Mat ORB_KNN_imgMatches; //// 筛选匹配,把距离太大的去掉 //// 这里使用的准则是去掉大于四倍最小距离的匹配 //vector< cv::DMatch > goodMatches; //double minDis = 9999; //for (size_t i = 0; i<matches.size(); i++) //{ // if (matches[i].distance < minDis) // minDis = matches[i].distance; //} //for (size_t i = 0; i<matches.size(); i++) //{ // if (matches[i].distance < 8 * minDis) // goodMatches.push_back(matches[i]); //} // 显示 good matches cv::drawMatches(rgb1, kp1, rgb2, kp2, inliers1, AKAZE_BF_imgMatches); cv::imwrite("F:/study work/Visual Odometry dev/VO_practice_2016.4/算法测试/KAZE算法/data/AKAZE-BF-Matches-inliers.jpg", AKAZE_BF_imgMatches); cv::drawMatches(rgb1, kp1, rgb2, kp2, goodMatches1, AKAZE_KNN_imgMatches); cv::imwrite("F:/study work/Visual Odometry dev/VO_practice_2016.4/算法测试/KAZE算法/data/AKAZE-Good-KNN-Matches.jpg", AKAZE_KNN_imgMatches); cv::resize(AKAZE_BF_imgMatches, AKAZE_BF_imgMatches, Size(AKAZE_BF_imgMatches.cols / 2, AKAZE_BF_imgMatches.rows / 2)); cv::imshow("AKAZE-BF-Matches-inliers", AKAZE_BF_imgMatches); cv::resize(AKAZE_KNN_imgMatches, AKAZE_KNN_imgMatches, Size(AKAZE_KNN_imgMatches.cols / 2, AKAZE_KNN_imgMatches.rows / 2)); cv::imshow("AKAZE-Good-KNN-Matches", AKAZE_KNN_imgMatches); cv::drawMatches(rgb1, kp3, rgb2, kp4, inliers2, ORB_BF_imgMatches); cv::imwrite("F:/study work/Visual Odometry dev/VO_practice_2016.4/算法测试/KAZE算法/data/ORB-BF-Matches-inliers.jpg", ORB_BF_imgMatches); cv::drawMatches(rgb1, kp3, rgb2, kp4, goodMatches2, ORB_KNN_imgMatches); cv::imwrite("F:/study work/Visual Odometry dev/VO_practice_2016.4/算法测试/KAZE算法/data/ORB-Good-KNN-Matches.jpg", ORB_KNN_imgMatches); cv::resize(ORB_BF_imgMatches, ORB_BF_imgMatches, Size(ORB_BF_imgMatches.cols / 2, ORB_BF_imgMatches.rows / 2)); cv::imshow("ORB-BF-Matches-inliers", ORB_BF_imgMatches); cv::resize(ORB_KNN_imgMatches, ORB_KNN_imgMatches, Size(ORB_KNN_imgMatches.cols / 2, ORB_KNN_imgMatches.rows / 2)); cv::imshow("ORB-Good-KNN-Matches", ORB_KNN_imgMatches); cv::waitKey(0);}
阅读全文
0 0
- KAZE匹配算法源码
- kaze算法的图像配准研究(2)-匹配
- KAZE 算法原理与源码分析(四)KAZE特征的性能分析与比较
- OpenCV学习笔记(30)KAZE 算法原理与源码分析(四)KAZE特征的性能分析与比较
- OpenCV学习笔记(31)KAZE 算法原理与源码分析(五)KAZE的源码优化及与SIFT的比较
- KAZE
- KAZE与SIFT算法比较
- OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波
- OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波
- 使用RANSAC提纯KAZE和AKAZE特征点,达到鲁棒匹配的效果(OpenCV 3.2.0下,源码)
- KMP匹配算法源码
- OpenCV学习笔记(28)KAZE 算法原理与源码分析(二)非线性尺度空间构建
- OpenCV学习笔记(29)KAZE 算法原理与源码分析(三)特征检测与描述
- 比较 KAZE 与 SIFT 的算法
- kaze算法的图像配准研究(1)-KAZE算法原理
- 一点一滴完全突破KAZE特征检测算法(4)
- KAZE FEATURES
- Python源码中的算法分析 之 字符串匹配算法
- linux 串口用户模式改为root模式
- Android5.0 Material design
- Noip2017 Day2T1 cheese
- Eclipse设置、调优、使用
- 世界坐标系与像素坐标系的点互相转换
- KAZE匹配算法源码
- C语言面向对象编程之六:配置文件解析
- linux ubuntu环境下安装jdk(要求网络畅通有一定网速)
- Linux命令行
- shell 脚本编程学习(三) 条件控制,循环控制
- ExtJS Button调用Ext.window.Window后,只能点开一次,第二次就点不开
- Shop项目Servlet抽取
- SystemServer到Launcher
- 库vector函数的熟悉