OpenCV实现摄像机标定和像素转换,surf寻找特征点,FLANN匹配算子进行匹配
最近做项目需要摄像机标定和图像转换,OpenCV可以较好的实现这个功能。我的这个例子可以生成两个摄像头的3x3转换矩阵。
但是因为摄像头本身存在成像畸变,尤其是全景摄像机,可能会有更加严重的成像畸变,所有如果试图通过计算两幅完整图像而得到转换单一矩阵,
这个矩阵并不能准确的反应出两幅图像像素之间的对应关系,尤其是靠近边缘区域的像素尤其如此。一个好的建议是将两幅图像分为若干个大小相等
也可以不等的块,分别计算每个块的转换矩阵,这样可以最大程度的降低摄像机成像畸变带来的转换误差。下面是源代码,但是这个代码没有实现分块
<span style="white-space:pre"> </span>//【1】载入原始图片Mat srcImage1 = imread("tt1.jpg", 1);Mat srcImage2 = imread("tt2.jpg", 1);if (!srcImage1.data || !srcImage2.data){printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false;}//【2】使用SURF算子检测关键点int minHessian = 600;//SURF算法中的hessian阈值SurfFeatureDetector detector(minHessian);//定义一个SurfFeatureDetector(SURF) 特征检测类对象 vector<KeyPoint> keypoints_object, keypoints_scene;//vector模板类,存放任意类型的动态数组//【3】调用detect函数检测出SURF特征关键点,保存在vector容器中detector.detect(srcImage1, keypoints_object);detector.detect(srcImage2, keypoints_scene);//【4】计算描述符(特征向量)SurfDescriptorExtractor extractor;Mat descriptors_object, descriptors_scene;extractor.compute(srcImage1, keypoints_object, descriptors_object);extractor.compute(srcImage2, keypoints_scene, descriptors_scene);//【5】使用FLANN匹配算子进行匹配FlannBasedMatcher matcher;vector< vector< DMatch > > matches;//matcher.match(descriptors_object, descriptors_scene, matches);matcher.knnMatch(descriptors_object, descriptors_scene, matches,2);double max_dist = 0; double min_dist = 100;//最小距离和最大距离vector<DMatch> goodMatches;for (unsigned int i = 0; i < matches.size(); i++){if (matches[i][0].distance < 0.6*matches[i][1].distance){goodMatches.push_back(matches[i][0]);}}//【6】计算出关键点之间距离的最大值和最小值for (unsigned j = 0; j < goodMatches.size(); j++){double dist = goodMatches[j].distance;if (dist < min_dist) min_dist = dist;if (dist > max_dist) max_dist = dist;}printf(">Max dist 最大距离 : %f \n", max_dist);printf(">Min dist 最小距离 : %f \n", min_dist);//【7】存下匹配距离小于3*min_dist的点对vector<DMatch>::iterator it;for (it = goodMatches.begin(); it != goodMatches.end();){if ((*it).distance > 3 * min_dist){it=goodMatches.erase(it);}else{it++;}}//绘制出匹配到的关键点Mat img_matches;drawMatches(srcImage1, keypoints_object, srcImage2, keypoints_scene,goodMatches, img_matches, Scalar::all(-1), Scalar::all(-1),vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);//定义两个局部变量vector<Point2f> obj;vector<Point2f> scene;//从匹配成功的匹配对中获取关键点for (unsigned int i = 0; i < goodMatches.size(); i++){obj.push_back(keypoints_object[goodMatches[i].queryIdx].pt);scene.push_back(keypoints_scene[goodMatches[i].trainIdx].pt);}Mat H = findHomography(obj, scene, CV_RANSAC);//计算透视变换 //从待测图片中获取四边角点vector<Point2f> obj_corners(4);obj_corners[0] = cvPoint(0, 0); obj_corners[1] = cvPoint(srcImage1.cols, 0);obj_corners[2] = cvPoint(srcImage1.cols, srcImage1.rows); obj_corners[3] = cvPoint(0, srcImage1.rows);vector<Point2f> scene_corners(4);//进行透视变换perspectiveTransform(obj_corners, scene_corners, H);//绘制出角点之间的直线line(img_matches, scene_corners[0] + Point2f(static_cast<float>(srcImage1.cols), 0), scene_corners[1] + Point2f(static_cast<float>(srcImage1.cols), 0), Scalar(255, 0, 123), 1);line(img_matches, scene_corners[1] + Point2f(static_cast<float>(srcImage1.cols), 0), scene_corners[2] + Point2f(static_cast<float>(srcImage1.cols), 0), Scalar(255, 0, 123), 1);line(img_matches, scene_corners[2] + Point2f(static_cast<float>(srcImage1.cols), 0), scene_corners[3] + Point2f(static_cast<float>(srcImage1.cols), 0), Scalar(255, 0, 123), 1);line(img_matches, scene_corners[3] + Point2f(static_cast<float>(srcImage1.cols), 0), scene_corners[0] + Point2f(static_cast<float>(srcImage1.cols), 0), Scalar(255, 0, 123), 1);//显示最终结果imshow("效果图", img_matches);
可以看出无论是特征点的选取还是匹配都是相当准确的,紫色的矩形框就是左边图像四个边角点通过转换到右边的效果,也是相当准确。所需时间是在1秒之内
OpenCV实现摄像机标定和像素转换,surf寻找特征点,FLANN匹配算子进行匹配相关推荐
- 用OpenCV进行摄像机标定
用OpenCV进行摄像机标定 照相机已经存在很长时间了.然而,随着廉价针孔相机在20世纪末的引入,日常生活中变得司空见惯.不幸的是,这种廉价伴随着它的代价:显著的扭曲.幸运的是,这些常数,通过校准和一 ...
- 基于opencv的摄像机标定
原理简述: 三维世界中的点的位置与其对应的二维投影,遵从以下公式: 其中, M表示三维世界中的点: [R|T]表示欧氏变换,是一个3*4矩阵 A表示相机参数矩阵,存放相机内部参数 P表示M ...
- Python+OpenCV:摄像机标定(Camera Calibration)
Python+OpenCV:摄像机标定(Camera Calibration) 理论 Some pinhole cameras introduce significant distortion to ...
- [OpenCV-Python] OpenCV 中摄像机标定和 3D 重构 部分 VII
部分 VII 摄像机标定和 3D 重构 OpenCV-Python 中文教程(搬运)目录 42 摄像机标定 目标 • 学习摄像机畸变以及摄像机的内部参数和外部参数 • 学习找到这些参数,对畸变图像进行 ...
- OpenCV-Python] OpenCV 中摄像机标定和 3D 重构 部分 VII
https://www.cnblogs.com/Undo-self-blog/p/8448500.html 42 摄像机标定 目标 • 学习摄像机畸变以及摄像机的内部参数和外部参数 • 学习找到这些参 ...
- 【OpenCV】摄像机标定+畸变校正
摄像机标定 本文目的在于记录如何使用MATLAB做摄像机标定,并通过opencv进行校正后的显示. 首先关于校正的基本知识通过OpenCV官网的介绍即可简单了解: http://docs.opencv ...
- 摄像机标定:像素焦距与毫米焦距转换
1.像素焦距与毫米焦距转换 fu = ku * dpx; fv = kv * dpy; 1) ku.kv分别为摄像机内参矩阵的x(u).y(v)方向的像素焦距; 2) fu.fv分别为摄像 ...
- Python+OpenCV学习(17)---摄像机标定
Python+OpenCV学习(17)---摄像机标定 原文:http://blog.csdn.net/firemicrocosm/article/details/48594897 利用python学 ...
- opencv 双目摄像头标定
我用的是opencv官方的例程,花了一天把代码大致注释了下,但是双目感觉好难,很多地方都不懂,都是在大佬们的博客找的资料 下面是对例程使用的说明 http://blog.csdn.net/t24755 ...
- 多摄像机标定和去畸变
Table of Contents 1.kalibr多摄像机标定 1.1 系统安装,环境配置:实测Ubuntu 16.04 1.2 多摄像机标定 2.OpenCV双目标定 3.Matlab多摄像机标定 ...
最新文章
- linux内核编译步骤!
- FD.io/VPP — DNS Plugin
- python编程入门经典教程-2020年5个经典python编程入门视频教程推荐学习
- 工作总结-基于R的数据分析
- ado.net连接mysql 类_C# ADO.NET 连接数据库常用到的类及基本操作格式
- 【linux 06】 linux中的用户权限、文件权限与目录权限
- tomcat,eclipse,sts绿色运行
- C语言 main 函数 - C语言零基础入门教程
- 【CSS3】CSS实现の全屏覆盖+居中显示+等比缩放
- centos6/7 yum安装mysql客户端和rpm包方式安装方式
- 学JAVA第十三天,方法、方法重载及构造函数
- T-SQL 之 游标
- numpy复习总结,为深度学习打下基础
- Linux系统批量压缩图片工具
- 雄迈网络摄像头RTSP直播
- win7计算机怎么初始化,win7怎么初始化电脑的方式
- iqooneo5桌面原子组件教程分享
- 终端安全防护技术研究(三)
- w ndows10系统怎么退出安全模式,Windows 10安全模式怎么解除
- lpad()函数oracle,oracle 中lpad的用法
热门文章
- 解决办法:java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_eye(III)J
- 已移植到loongarch64的libffi源码目录
- 代码管理学:首次提出代码的平台化思维
- 全网首发:configure: error: cannot guess build type; you must specify one
- 奇怪的加拿大:一方面大力禁烟,另一方面放松大麻
- 下了高铁直接上地铁,多方便
- 遇到INSTALL_FAILED_VERIFICATION_FAILURE怎么办
- delphi 剪切板变量_delphi读写剪贴板
- shell 获取时间
- android自定义view案例,Android自定义View,你摸的透透的了?