代码如下:

// 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

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

  1. XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem F. Matrix Game

    题目: Problem F. Matrix GameInput file: standard inputOutput file: standard inputTime limit: 1 secondM ...

  2. 2D-2D:对极几何 基础矩阵F 本质矩阵E 单应矩阵H

    对极约束 \[ \boldsymbol{x}_{2}^{T} \boldsymbol{F} \boldsymbol{x}_{1}=\boldsymbol{0} \quad \hat{\boldsymb ...

  3. Halcon学习之六:获取Image图像中Region区域的特征参数

    area_center_gray ( Regions, Image : : : Area, Row, Column )    计算Image图像中Region区域的面积Area和重心(Row,Colu ...

  4. 前端 JS 获取 Image 图像 宽高 尺寸

    前端 JS 获取 Image 图像 宽高 尺寸 简介 项目中用到获取图片的原始尺寸,然后适配宽高:网上的大部分前端解决方案,都是new Image()后,在onload事件中获取image的尺寸. 在 ...

  5. vc/mfc获取rgb图像数据后动态显示及保存图片的方法

    vc/mfc获取rgb图像数据后动态显示及保存图片的方法 该情况可用于视频通信中获取的位图数据回放显示或显示摄像头捕获的本地图像 第一种方法 #include<vfw.h> 加载 vfw3 ...

  6. Html5 中获取镜像图像 - 解决 WebGL 中纹理倒置问题

    Html5 中获取镜像图像 - 解决 WebGL 中纹理倒置问题 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致& ...

  7. WordPress获取特色图像的链接地址

    为什么要获取WordPress的特色图像呢? 这主要是因为,我们已经写好了静态模板文件,只有获取WordPress特色图像地址插入进去就可以了,非常方便. 还有就是有的时候,我们需要设置图片的宽度为1 ...

  8. Hi3516开发笔记(十):Qt从VPSS中获取通道图像数据存储为jpg文件

    前言   上一篇已经将himpp套入qt的基础上进行开发.那么qt中拿到frame则是很关键的交互,这是qt与海思可能编解码交叉开发的关键步骤.   受限制   因为直接配置sample的vi比较麻烦 ...

  9. 【枚举】【最小表示法】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem F. Matrix Game

    给你一个n*m的字符矩阵,将横向(或纵向)全部裂开,然后以任意顺序首尾相接,然后再从中间任意位置切开,问你能构成的字典序最大的字符串. 以横向切开为例,纵向类似. 将所有横排从大到小排序,枚举最后切开 ...

  10. 【图像处理】Golang 获取JPG图像的宽高

    一.背景 有些业务需要判断图片的宽高,来做一些图片相关缩放,旋转等基础操作. 但是图片缩放,旋转,拼接等操作需要将图片从 JPG 格式转成 RGBA 格式操作,操作完毕后,再转回 JPG 图片. 那如 ...

随机推荐

  1. spring需要在https下进行开发配置方法

    keytool -genkey -alias tomcathttps -keyalg RSA -keysize 2048 -keystore sang.p12 -validity 365 genkey ...

  2. ESP8266 + MQTT (platformio 开发环境)加用户名和密码

    ESP8266 + MQTT git 地址: https://gitee.com/zhudachangs/esp8266-mqtt.git (如果无法打开说明在审核) 引用库 include < ...

  3. docker新建自定义网桥,实现不同主机容器互联

    不同主机间的容器网络互联,网络上的所有教程都是通过open vswitch等虚拟网桥方式实现的,但是最近本人发现可以直接通过配置网桥实现网络的互联,而不用安装配置open vswitch.在这里分享一 ...

  4. 如何在HarmonyOS Next中编译React-Native包

    一.创作背景 鸿蒙既出,万众瞩目.作为国内操作系统自力更生的代表,它承载着十四亿中国人民的强烈期望,系国家安全和国运于一身.就算抛开爱国情怀不谈,作为一名软件开发人员,偌大的就业市场,海量的翻身机会就 ...

  5. VS项目无法加载js或其他文件

    1.查看文件位置项目是否加载进去 2.将文件显示,再次找到该目录将文件添加到项目中 3.启动调试,

  6. java——棋牌类游戏五子棋(webwzq1.0)之三(Msg)

    package msg; import java.io.ObjectInputStream; import java.net.DatagramSocket; /******************** ...

  7. java——棋牌类游戏斗地主(singleddz3.0)

    这是本人最近一段时间写的斗地主的java代码,大体框架都实现了,主要缺少,AI的智能算法. 下载地址http://download.csdn.net/detail/novelly/5695445 im ...

  8. 使用 Apache MINA 开发高性能网络应用程序

    Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络 ...

  9. 秒懂Redis

    一.redis简介 Redis 是C语言开发的一个开源高性能键值对的内存数据库,可以用来做数据库.缓存.消息中间件等场景,是一种NoSQL(not-only sql,非关系型数据库)的数据库 二.Re ...

  10. ClickHouse之物化MySQL

    Creates ClickHouse database with all the tables existing in MySQL, and all the data in those tables. ...