最近做项目需要摄像机标定和图像转换,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匹配算子进行匹配相关推荐

  1. 用OpenCV进行摄像机标定

    用OpenCV进行摄像机标定 照相机已经存在很长时间了.然而,随着廉价针孔相机在20世纪末的引入,日常生活中变得司空见惯.不幸的是,这种廉价伴随着它的代价:显著的扭曲.幸运的是,这些常数,通过校准和一 ...

  2. 基于opencv的摄像机标定

    原理简述: 三维世界中的点的位置与其对应的二维投影,遵从以下公式:   其中,  M表示三维世界中的点:  [R|T]表示欧氏变换,是一个3*4矩阵  A表示相机参数矩阵,存放相机内部参数  P表示M ...

  3. Python+OpenCV:摄像机标定(Camera Calibration)

    Python+OpenCV:摄像机标定(Camera Calibration) 理论 Some pinhole cameras introduce significant distortion to ...

  4. [OpenCV-Python] OpenCV 中摄像机标定和 3D 重构 部分 VII

    部分 VII 摄像机标定和 3D 重构 OpenCV-Python 中文教程(搬运)目录 42 摄像机标定 目标 • 学习摄像机畸变以及摄像机的内部参数和外部参数 • 学习找到这些参数,对畸变图像进行 ...

  5. OpenCV-Python] OpenCV 中摄像机标定和 3D 重构 部分 VII

    https://www.cnblogs.com/Undo-self-blog/p/8448500.html 42 摄像机标定 目标 • 学习摄像机畸变以及摄像机的内部参数和外部参数 • 学习找到这些参 ...

  6. 【OpenCV】摄像机标定+畸变校正

    摄像机标定 本文目的在于记录如何使用MATLAB做摄像机标定,并通过opencv进行校正后的显示. 首先关于校正的基本知识通过OpenCV官网的介绍即可简单了解: http://docs.opencv ...

  7. 摄像机标定:像素焦距与毫米焦距转换

    1.像素焦距与毫米焦距转换      fu = ku * dpx; fv = kv *  dpy; 1) ku.kv分别为摄像机内参矩阵的x(u).y(v)方向的像素焦距; 2) fu.fv分别为摄像 ...

  8. Python+OpenCV学习(17)---摄像机标定

    Python+OpenCV学习(17)---摄像机标定 原文:http://blog.csdn.net/firemicrocosm/article/details/48594897 利用python学 ...

  9. opencv 双目摄像头标定

    我用的是opencv官方的例程,花了一天把代码大致注释了下,但是双目感觉好难,很多地方都不懂,都是在大佬们的博客找的资料 下面是对例程使用的说明 http://blog.csdn.net/t24755 ...

  10. 多摄像机标定和去畸变

    Table of Contents 1.kalibr多摄像机标定 1.1 系统安装,环境配置:实测Ubuntu 16.04 1.2 多摄像机标定 2.OpenCV双目标定 3.Matlab多摄像机标定 ...

最新文章

  1. linux内核编译步骤!
  2. FD.io/VPP — DNS Plugin
  3. python编程入门经典教程-2020年5个经典python编程入门视频教程推荐学习
  4. 工作总结-基于R的数据分析
  5. ado.net连接mysql 类_C# ADO.NET 连接数据库常用到的类及基本操作格式
  6. 【linux 06】 linux中的用户权限、文件权限与目录权限
  7. tomcat,eclipse,sts绿色运行
  8. C语言 main 函数 - C语言零基础入门教程
  9. 【CSS3】CSS实现の全屏覆盖+居中显示+等比缩放
  10. centos6/7 yum安装mysql客户端和rpm包方式安装方式
  11. 学JAVA第十三天,方法、方法重载及构造函数
  12. T-SQL 之 游标
  13. numpy复习总结,为深度学习打下基础
  14. Linux系统批量压缩图片工具
  15. 雄迈网络摄像头RTSP直播
  16. win7计算机怎么初始化,win7怎么初始化电脑的方式
  17. iqooneo5桌面原子组件教程分享
  18. 终端安全防护技术研究(三)
  19. w ndows10系统怎么退出安全模式,Windows 10安全模式怎么解除
  20. lpad()函数oracle,oracle 中lpad的用法

热门文章

  1. 解决办法:java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_eye(III)J
  2. 已移植到loongarch64的libffi源码目录
  3. 代码管理学:首次提出代码的平台化思维
  4. 全网首发:configure: error: cannot guess build type; you must specify one
  5. 奇怪的加拿大:一方面大力禁烟,另一方面放松大麻
  6. 下了高铁直接上地铁,多方便
  7. 遇到INSTALL_FAILED_VERIFICATION_FAILURE怎么办
  8. delphi 剪切板变量_delphi读写剪贴板
  9. shell 获取时间
  10. android自定义view案例,Android自定义View,你摸的透透的了?