首页 > 其他分享 >[转]OpenCV_Find Basis F-Matrix and computeCorrespondEpilines(获取一对图像的基础矩阵及对应极线)

[转]OpenCV_Find Basis F-Matrix and computeCorrespondEpilines(获取一对图像的基础矩阵及对应极线)

时间:2022-10-09 17:13:39浏览次数:90  
标签:std partmatches computeCorrespondEpilines Matrix Basis matches image2 cv 255

代码如下:

// BasisMatrixCalculate.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
#include  <iostream>
 
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
//引用cv::KeyPoint 特征检测器通用接口
#include <opencv2/features2d/features2d.hpp> 
# include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/nonfree/nonfree.hpp> //引用features2d.hpp中 SurfFeatureDetector
#include <opencv2/legacy/legacy.hpp>  
int main()
{
    //读取2张图像
    cv::Mat image1 = cv::imread("../../aTestImage/church01.jpg", 0);
    cv::Mat image2 = cv::imread("../../aTestImage/church03.jpg", 0);
    if (!image1.data || !image2.data)
        return 0;
    //使用SURF特征 获取图像特征点
    std::vector<cv::KeyPoint> keyPoints1;
    std::vector<cv::KeyPoint> keyPoints2;
    cv::SurfFeatureDetector surf(3000);
    surf.detect(image1, keyPoints1);
    surf.detect(image2, keyPoints2); //获取两幅图像的特征点
 
    // //展示图像中的keyPoints
    //cv::Mat imagekeyPt;
    //cv::drawKeypoints(image1, keyPoints1, imagekeyPt, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
    //cv::namedWindow("image1SURFkeyPt");
    //cv::imshow("image1SURFkeyPt", imagekeyPt);
    //cv::drawKeypoints(image2, keyPoints2, imagekeyPt, cv::Scalar(255, 255, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
    //cv::namedWindow("image2SURFkeyPt");
    //cv::imshow("image2SURFkeyPt", imagekeyPt);
 
    //通过特征点获取描述子
    cv::SurfDescriptorExtractor  surfDesc;  // 构造描述子提取器
    cv::Mat descriptors1, descriptors2;  //描述子记录局部强度差值/梯度变化/位置等信息
    surfDesc.compute(image1, keyPoints1, descriptors1);
    surfDesc.compute(image2, keyPoints2, descriptors2);
 
    //匹配图像的描述子 descriptors
    cv::BruteForceMatcher< cv::L2<float> > matcher; //构造匹配器
    std::vector<cv::DMatch> matches; //匹配描述子
    matcher.match(descriptors1, descriptors2, matches);
    std::cout << "matches size= " << matches.size() << std::endl;
 
    //选择部分描述子 使用 一对图像的基础矩阵 进行匹配观测
    std::vector<cv::DMatch> partmatches; //部分匹配描述子 | 特征点对 的对应 索引结构体
    partmatches.push_back(matches[14]);  //选择第n个匹配描述子
    partmatches.push_back(matches[16]);
    partmatches.push_back(matches[141]);
    partmatches.push_back(matches[242]);
    partmatches.push_back(matches[236]);
    partmatches.push_back(matches[238]);
    //partmatches.push_back(matches[100]);
    partmatches.push_back(matches[200]);
 
 
    //画出选择的匹配描述子 两幅图像连线
    cv::Mat imagePartMatches;
    cv::drawMatches(image1, keyPoints1, image2, keyPoints2,
        partmatches, imagePartMatches, cv::Scalar(255, 255, 255));
    cv::namedWindow("imagePartMatches");
    cv::imshow("imagePartMatches", imagePartMatches);
 
    //将一维向量的keyPoints点转换成二维的Point2f点
    std::vector <int> pointIndexes1;//记录选择的匹配特征点的索引向量
    std::vector <int> pointIndexes2;
 
    for (std::vector<cv::DMatch>::const_iterator it = partmatches.begin();
        it != partmatches.end(); ++it)
    {
        pointIndexes1.push_back(it->queryIdx); //查询图像1特征点索引
        pointIndexes2.push_back(it->trainIdx);  //训练图像2特征点索引
    }
    std::vector <cv::Point2f>  selPoints1, selPoints2;
    cv::KeyPoint::convert(keyPoints1, selPoints1, pointIndexes1);//将索引指定的 特征点 转换成2D点
    cv::KeyPoint::convert(keyPoints2, selPoints2, pointIndexes2);
    画出转换后的点二维点到原图像
    std::vector<cv::Point2f>::const_iterator  it = selPoints1.begin();
    //while (it != selPoints1.end())
    //{
    //    cv::circle(image1, *it, 3, cv::Scalar(255, 255, 255), 5);
    //    ++it;
    //}
    it = selPoints2.begin();
    while (it != selPoints2.end())
    {
        cv::circle(image2, *it, 3, cv::Scalar(255, 255, 255), 2);
        ++it;
    }
    //cv::namedWindow("image1");
    //cv::imshow("image1", image1);
    //cv::namedWindow("image2");
    //cv::imshow("image2", image2);
 
    // 获取该对图像的基础矩阵 (使用7个匹配描述子matches) CV_FM_7POINT
 
    cv::Mat fundemental = cv::findFundamentalMat(cv::Mat(selPoints1), cv::Mat(selPoints2),CV_FM_8POINT);//CV_FM_LMEDS
    std::cout << "F-Matrix size= " << fundemental.rows << "," << fundemental.cols << std::endl;
    
    //使用基础矩阵 在对应图像上绘制外极线
    std::vector<cv::Vec3f> lines1; //存储外极线
    cv::computeCorrespondEpilines(cv::Mat(selPoints1), 1, fundemental, lines1);//获取图像1中的二维特征点 在图像2中对应的外极线
    for (std::vector<cv::Vec3f>::const_iterator it = lines1.begin(); 
          it != lines1.end(); ++it)
    {
        cv::line(image2, 
            cv::Point(0, -(*it)[2] / (*it)[1] ),
            cv::Point(image2.cols ,  -( (*it)[2] + (*it)[0] * image2.cols )/(*it)[1] ),
            cv::Scalar(255,255,255));
    }
    cv::namedWindow("Image2 Epilines");
    cv::imshow("Image2 Epilines", image2);
 
    cv::waitKey(0);
    return 0;
}

结果:

 

原文链接:https://blog.csdn.net/shyjhyp11/article/details/66526685

 

标签:std,partmatches,computeCorrespondEpilines,Matrix,Basis,matches,image2,cv,255
From: https://www.cnblogs.com/rainbow70626/p/16772821.html

相关文章

  • Page Rank: Graph as Matrix
    PageRank:GraphasMatrix在google中,会对页面的重要性进行排序,这节课就是讲的pagerank及相关引申。前置知识--马尔可夫矩阵马尔科夫矩阵(MarkovMatrices)的定义:矩......
  • POJ-3494 Largest Submatrix of All 1’s
    LargestSubmatrixofAll1’s单调栈感觉很经典的题目,不知道为啥就没做出来从第\(i\)行来说,\(a_{ij}\)可以抽象成一个高度为\(x\)的山峰,\(x\)取决于在第\(j\)......
  • POJ 3494 Largest Submatrix of All 1’s(单调栈)
    POJ3494LargestSubmatrixofAll1’s(单调栈)题意:​ 给出一个01矩阵,请找出其中最大的全部为1构成的子矩阵。矩阵大小为\(2000*2000\)思路:​ 我们把问题分解到每一......
  • 311. Sparse Matrix Multiplication 稀疏矩阵的乘法
    Giventwo sparsematrices mat1 ofsize mxk and mat2 ofsize kxn,returntheresultof mat1xmat2.Youmayassumethatmultiplicationisalwayspo......
  • [Oracle] LeetCode 54 Spiral Matrix 模拟
    Givenanmxnmatrix,returnallelementsofthematrixinspiralorder.Solution点击查看代码classSolution{public:vector<int>spiralOrder(vector<ve......
  • gym 102586 G. matrix inversions
    考虑一个对子对\(A,B\)的贡献,如果\(x_1\ley_1,x_2\ley_2\)的一对点会贡献\(0,0\)或\(+1,+1\),\(x_1<x_2,y_1>y_2\)会贡献\(0,+1\)或\(+1,0\)。设第一种对子最......
  • 深入浅出WPF变换(Transform)之矩阵(Matrix)
    背景知识Matrix是一个用于在二维坐标系中进行坐标转换的3*3仿射变换矩阵。什么是仿射变换?为什么是3*3,不是2*2?好的,让我们来复习一下(以下内容来自百度百科):仿射变换,又称仿......
  • [Google] LeetCode 329 Longest Increasing Path in a Matrix 记忆化搜索
    Givenanmxnintegersmatrix,returnthelengthofthelongestincreasingpathinmatrix.Fromeachcell,youcaneithermoveinfourdirections:left,right......
  • [Google] LeetCode 562 Longest Line of Consecutive One in Matrix
    Givenanmxnbinarymatrixmat,returnthelengthofthelongestlineofconsecutiveoneinthematrix.Thelinecouldbehorizontal,vertical,diagonal,or......
  • 混淆矩阵(Confusion Matrix)
    混淆矩阵(ConfusionMatrix)1.混淆矩阵引入在机器学习领域,当我们想要衡量一个模型的优劣时,经常用到一些分析指标,如:错误率、准确率等。但是这两个指标并不能满足所有任务......