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 24 Python
Python的Flask框架中集成CKeditor富文本编辑器的教程
Jun 13 Python
在 Python 应用中使用 MongoDB的方法
Jan 05 Python
Python实现将SQLite中的数据直接输出为CVS的方法示例
Jul 13 Python
python3中获取文件当前绝对路径的两种方法
Apr 26 Python
使用Python批量修改文件名的代码实例
Jan 24 Python
python 直接赋值和copy的区别详解
Aug 07 Python
python中web框架的自定义创建
Sep 08 Python
python scipy卷积运算的实现方法
Sep 16 Python
浅析python函数式编程
Sep 26 Python
Python入门基础之数字字符串与列表
Feb 01 Python
Python基础知识学习之类的继承
May 31 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 日,周,月点击排行统计
2012/01/11 PHP
PHP调用Linux命令权限不足问题解决方法
2015/02/07 PHP
javascript实现的动态文字变换
2007/07/28 Javascript
JavaScript 学习笔记之一jQuery写法图片等比缩放以及预加载
2012/06/28 Javascript
javascript使用中为什么10..toString()正常而10.toString()出错呢
2013/01/11 Javascript
node.js中的buffer.length方法使用说明
2014/12/14 Javascript
javascript电商网站抢购倒计时效果实现
2015/11/19 Javascript
利用JavaScript阻止表单提交的两种方法
2016/08/11 Javascript
AngularJS入门教程引导程序
2016/08/18 Javascript
layer实现弹窗提交信息
2016/12/12 Javascript
JavaScript正则表达式替换字符串中图片地址(img src)的方法
2017/01/13 Javascript
JS日程管理插件FullCalendar中文说明文档
2017/02/06 Javascript
Bootstrap弹出框之自定义悬停框标题、内容和样式示例代码
2017/07/11 Javascript
详解基于vue-router的动态权限控制实现方案
2017/09/28 Javascript
vue.js自定义组件directives的实例代码
2018/11/09 Javascript
JS数组降维的实现Array.prototype.concat.apply([], arr)
2020/04/28 Javascript
Python字符串格式化
2015/06/15 Python
Python中Collections模块的Counter容器类使用教程
2016/05/31 Python
python 地图经纬度转换、纠偏的实例代码
2018/08/06 Python
python 有效的括号的实现代码示例
2019/11/11 Python
django框架cookie和session用法实例详解
2019/12/10 Python
在flask中使用python-dotenv+flask-cli自定义命令(推荐)
2020/01/05 Python
Python 文件数据读写的具体实现
2020/01/24 Python
安装完Python包然后找不到模块的解决步骤
2020/02/13 Python
Python中logger日志模块详解
2020/08/04 Python
Kidsroom台湾:来自德国的婴儿用品
2017/12/11 全球购物
中专生自荐信
2013/10/12 职场文书
如何打造一封优秀的留学推荐信
2014/01/25 职场文书
医院节能减排方案
2014/06/13 职场文书
个人四风问题对照检查材料
2014/10/01 职场文书
2014办公室年度工作总结
2014/12/09 职场文书
2015年小学二年级班主任工作总结
2015/05/21 职场文书
大学班长竞选稿
2015/11/20 职场文书
2015元旦感言
2015/12/09 职场文书
环境保护宣传标语大全!
2019/06/28 职场文书
React列表栏及购物车组件使用详解
2021/06/28 Javascript