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