opencv3/C++ 平面对象识别&透视变换方式


Posted in Python onDecember 11, 2019

findHomography( )

函数findHomography( )找到两个平面之间的透视变换H。

参数说明:

Mat findHomography( 
InputArray srcPoints, //原始平面中点的坐标
InputArray dstPoints, //目标平面中点的坐标
int method = 0, //用于计算单应性矩阵的方法
double ransacReprojThreshold = 3, 
OutputArray mask=noArray(), //通过鲁棒法(RANSAC或LMEDS)设置的可选输出掩码
const int maxIters = 2000, //RANSAC迭代的最大次数,2000是它可以达到的最大值
const double confidence = 0.995 //置信度
);

用于计算单应性矩阵的方法有:

0 :使用所有点的常规方法;

RANSAC:基于RANSAC的鲁棒法;

LMEDS :最小中值鲁棒法;

RHO :基于PROSAC的鲁棒法;

opencv3/C++ 平面对象识别&透视变换方式

被最小化。如果参数方法被设置为默认值0,则函数使用所有的点对以简单的最小二乘方案计算初始单应性估计。

然而,如果不是所有的点对 opencv3/C++ 平面对象识别&透视变换方式 都符合刚性透视变换(也就是说有一些异常值),那么这个初始估计就会很差。在这种情况下,可以使用三种鲁棒法之一。方法RANSAC,LMeDS和RHO尝试使用这个子集和一个简单的最小二乘算法来估计单应矩阵的各个随机子集(每个子集有四对),然后计算计算的单应性的质量/良好度(这是RANSAC的内点数或LMeD的中值重投影误差)。然后使用最佳子集来产生单应矩阵的初始估计和内点/外点的掩码。

不管方法是否鲁棒,计算的单应性矩阵都用Levenberg-Marquardt方法进一步细化(仅在鲁棒法的情况下使用inlier)以更多地减少再投影误差。

RANSAC和RHO方法几乎可以处理任何异常值的比率,但需要一个阈值来区分异常值和异常值。 LMeDS方法不需要任何阈值,但只有在超过50%的内部值时才能正常工作。最后,如果没有异常值且噪声相当小,则使用默认方法(method = 0)。

perspectiveTransform()

函数perspectiveTransform()执行矢量的透视矩阵变换。

参数说明:

void perspectiveTransform(
InputArray src, //输入双通道或三通道浮点数组/图像
OutputArray dst, //输出与src相同大小和类型的数组/图像
InputArray m //3x3或4x4浮点转换矩阵
);

平面对象识别:

#include<opencv2/opencv.hpp>
#include<opencv2/xfeatures2d.hpp>
using namespace cv;
using namespace cv::xfeatures2d;

int main()
{
 Mat src1,src2;
 src1 = imread("E:/image/image/card.jpg");
 src2 = imread("E:/image/image/cards.jpg");
 if (src1.empty() || src2.empty())
 {
  printf("can ont load images....\n");
  return -1;
 }
 imshow("image1", src1);
 imshow("image2", src2);

 int minHessian = 400;
 //选择SURF特征
 Ptr<SURF>detector = SURF::create(minHessian);
 std::vector<KeyPoint>keypoints1;
 std::vector<KeyPoint>keypoints2;
 Mat descriptor1, descriptor2;
 //检测关键点并计算描述符
 detector->detectAndCompute(src1, Mat(), keypoints1, descriptor1);
 detector->detectAndCompute(src2, Mat(), keypoints2, descriptor2);

 //基于Flann的描述符匹配器
 FlannBasedMatcher matcher;
 std::vector<DMatch>matches;
 //从查询集中查找每个描述符的最佳匹配
 matcher.match(descriptor1, descriptor2, matches);
 double minDist = 1000;
 double maxDist = 0;
 for (int i = 0; i < descriptor1.rows; i++)
 {
  double dist = matches[i].distance;
  printf("%f \n", dist);
  if (dist > maxDist)
  {
   maxDist = dist;
  }
  if (dist < minDist)
  {
   minDist = dist;
  }

 }
 //DMatch类用于匹配关键点描述符的
 std::vector<DMatch>goodMatches;
 for (int i = 0; i < descriptor1.rows; i++)
 {
  double dist = matches[i].distance;
  if (dist < max(2*minDist, 0.02))
  {
   goodMatches.push_back(matches[i]);
  }
 }
 Mat matchesImg;
 drawMatches(src1, keypoints1, src2, keypoints2, goodMatches, matchesImg, Scalar::all(-1), 
  Scalar::all(-1), std::vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

 std::vector<Point2f>point1, point2;
 for (int i = 0; i < goodMatches.size(); i++)
 {
  point1.push_back(keypoints1[goodMatches[i].queryIdx].pt);
  point2.push_back(keypoints2[goodMatches[i].trainIdx].pt);
 }

 Mat H = findHomography(point1, point2, RANSAC);
 std::vector<Point2f>cornerPoints1(4);
 std::vector<Point2f>cornerPoints2(4);
 cornerPoints1[0] = Point(0, 0);
 cornerPoints1[1] = Point(src1.cols, 0);
 cornerPoints1[2] = Point(src1.cols, src1.rows);
 cornerPoints1[3] = Point(0,src1.rows);
 perspectiveTransform(cornerPoints1, cornerPoints2, H);

 //绘制出变换后的目标轮廓,由于左侧为图像src2故坐标点整体右移src1.cols
 line(matchesImg, cornerPoints2[0] + Point2f(src1.cols, 0), cornerPoints2[1] + Point2f(src1.cols, 0), Scalar(0,255,255), 4, 8, 0);
 line(matchesImg, cornerPoints2[1] + Point2f(src1.cols, 0), cornerPoints2[2] + Point2f(src1.cols, 0), Scalar(0,255,255), 4, 8, 0);
 line(matchesImg, cornerPoints2[2] + Point2f(src1.cols, 0), cornerPoints2[3] + Point2f(src1.cols, 0), Scalar(0,255,255), 4, 8, 0);
 line(matchesImg, cornerPoints2[3] + Point2f(src1.cols, 0), cornerPoints2[0] + Point2f(src1.cols, 0), Scalar(0,255,255), 4, 8, 0);

 //在原图上绘制出变换后的目标轮廓
 line(src2, cornerPoints2[0], cornerPoints2[1], Scalar(0,255,255), 4, 8, 0);
 line(src2, cornerPoints2[1], cornerPoints2[2], Scalar(0,255,255), 4, 8, 0);
 line(src2, cornerPoints2[2], cornerPoints2[3], Scalar(0,255,255), 4, 8, 0);
 line(src2, cornerPoints2[3], cornerPoints2[0], Scalar(0,255,255), 4, 8, 0);

 imshow("output", matchesImg);
 imshow("output2", src2);

 waitKey();
 return 0;
}

opencv3/C++ 平面对象识别&amp;透视变换方式

opencv3/C++ 平面对象识别&amp;透视变换方式

opencv3/C++ 平面对象识别&amp;透视变换方式

以上这篇opencv3/C++ 平面对象识别&透视变换方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
用Python创建声明性迷你语言的教程
Apr 13 Python
Python实现的数据结构与算法之双端队列详解
Apr 22 Python
Python线程指南详细介绍
Jan 05 Python
itchat接口使用示例
Oct 23 Python
python调用API实现智能回复机器人
Apr 10 Python
python实现机器学习之元线性回归
Sep 06 Python
Python2和Python3之间的str处理方式导致乱码的讲解
Jan 03 Python
用Python解决x的n次方问题
Feb 08 Python
numpy和pandas中数组的合并、拉直和重塑实例
Jun 28 Python
Python单元测试与测试用例简析
Nov 09 Python
Python集成开发工具Pycharm的安装和使用详解
Mar 18 Python
python list等分并从等分的子集中随机选取一个数
Nov 16 Python
Python Lambda函数使用总结详解
Dec 11 #Python
Python迭代器模块itertools使用原理解析
Dec 11 #Python
Python+Selenium+phantomjs实现网页模拟登录和截图功能(windows环境)
Dec 11 #Python
Python partial函数原理及用法解析
Dec 11 #Python
opencv3/python 鼠标响应操作详解
Dec 11 #Python
通过实例简单了解Python中yield的作用
Dec 11 #Python
opencv3/Python 稠密光流calcOpticalFlowFarneback详解
Dec 11 #Python
You might like
基于PHP+MySQL的聊天室设计
2006/10/09 PHP
CodeIgniter php mvc框架 中国网站
2008/05/26 PHP
php中json_encode处理gbk与gb2312中文乱码问题的解决方法
2014/07/10 PHP
利用ajax和PHP实现简单的流程管理
2017/03/23 PHP
php生成HTML文件的类方法
2019/10/11 PHP
javascript之对系统的toFixed()方法的修正
2007/05/08 Javascript
文本框文本自动补全效果示例分享
2014/01/19 Javascript
js用拖动滑块来控制图片大小的方法
2015/02/27 Javascript
nodejs创建web服务器之hello world程序
2015/08/20 NodeJs
通过原生JS实现为元素添加事件的方法
2016/11/23 Javascript
Jquery与Bootstrap实现后台管理页面增删改查功能示例
2017/01/22 Javascript
angular.js指令中transclude选项及ng-transclude指令详解
2017/05/24 Javascript
Angular 4依赖注入学习教程之ClassProvider的使用(三)
2017/06/04 Javascript
JS表单提交验证、input(type=number) 去三角 刷新验证码
2017/06/21 Javascript
AngularJS 实现点击按钮获取验证码功能实例代码
2017/07/13 Javascript
详解angularjs的数组传参方式的简单实现
2017/07/28 Javascript
如何在 JavaScript 中更好地利用数组
2018/09/27 Javascript
详解可以用在VS Code中的正则表达式小技巧
2019/05/14 Javascript
Python生成随机数的方法
2014/01/14 Python
python类继承与子类实例初始化用法分析
2015/04/17 Python
深入浅析Python传值与传址
2018/07/10 Python
对python判断是否回文数的实例详解
2019/02/08 Python
Python通过for循环理解迭代器和生成器实例详解
2019/02/16 Python
浅谈python3.6的tkinter运行问题
2019/02/22 Python
详解python 模拟豆瓣登录(豆瓣6.0)
2019/04/18 Python
python对矩阵进行转置的2种处理方法
2019/07/17 Python
opencv3/Python 稠密光流calcOpticalFlowFarneback详解
2019/12/11 Python
Python基于模块Paramiko实现SSHv2协议
2020/04/28 Python
使用Numpy对特征中的异常值进行替换及条件替换方式
2020/06/08 Python
基于nexus3配置Python仓库过程详解
2020/06/15 Python
德国化妆品和天然化妆品网上商店:kosmetikfuchs.de
2017/06/09 全球购物
C语言怎样定义和声明全局变量和函数最好
2013/11/26 面试题
巾帼文明岗申报材料
2014/05/01 职场文书
优秀少先队辅导员先进事迹材料
2014/05/18 职场文书
搞笑老公保证书
2015/02/26 职场文书
浙江省杭州市平均工资标准是多少?
2019/07/09 职场文书