保持奋斗的连续性,你将无坚不摧!!!!

1.棋盘格制作c++,相机纠正
2.图片获取,相机纠正
做好棋盘格,进行相机纠偏。纠偏原理,网上一堆直接查。直接上代码。

//运行环境 VS2019+opencv3.4.10 已测试  VS2015+opencv3.2已测试
// time:2021.6.28
#include <opencv2\opencv.hpp>
#include <fstream>
using namespace std;
using namespace cv;int main()
{ofstream fout("caliberation_result.txt");  /**    保存定标结果的文件     **//************************************************************************读取每一幅图像,从中提取出角点,然后对角点进行亚像素精确化*************************************************************************/cout << "开始提取角点………………" << endl;int image_count = 14;                    /****    图像数量     ****/Size board_size = Size(5, 7);            /****    定标板上每行、列的角点数       ****/vector<Point2f> corners;                  /****    缓存每幅图像上检测到的角点       ****/vector<vector<Point2f>>  corners_Seq;    /****  保存检测到的所有角点       ****/vector<Mat>  image_Seq;int successImageNum = 0;                /****   成功提取角点的棋盘图数量    ****/int count = 0;for (int i = 0; i != image_count; i++){cout << "Frame #" << i + 1 << "..." << endl;string imageFileName;std::stringstream StrStm;StrStm << i + 1;StrStm >> imageFileName;imageFileName += ".jpg";cv::Mat image = imread(imageFileName);if (image.empty()){std::cout << "no photo....\n";return -1;}/* 提取角点 */Mat imageGray;cvtColor(image, imageGray, CV_BGR2GRAY);bool patternfound = findChessboardCorners(image, board_size, corners, CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE +CALIB_CB_FAST_CHECK);if (!patternfound){cout << "找不到角点,需删除图片文件" << imageFileName << "重新排列文件名,再次标定" << endl;getchar();exit(1);}else{/* 亚像素精确化 */cornerSubPix(imageGray, corners, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));/* 绘制检测到的角点并保存 */Mat imageTemp = image.clone();for (int j = 0; j < corners.size(); j++){circle(imageTemp, corners[j], 10, Scalar(0, 0, 255), 2, 8, 0);}string imageFileName;std::stringstream StrStm;StrStm << i + 1;StrStm >> imageFileName;imageFileName += "_corner.jpg";imwrite(imageFileName, imageTemp);cout << "Frame corner#" << i + 1 << "...end" << endl;count = count + corners.size();successImageNum = successImageNum + 1;corners_Seq.push_back(corners);}image_Seq.push_back(image);}cout << "角点提取完成!\n";/************************************************************************摄像机定标*************************************************************************/cout << "开始定标………………" << endl;Size square_size = Size(20, 20);vector<vector<Point3f>>  object_Points;        /****  保存定标板上角点的三维坐标   ****/Mat image_points = Mat(1, count, CV_32FC2, Scalar::all(0));  /*****   保存提取的所有角点   *****/vector<int>  point_counts;/* 初始化定标板上角点的三维坐标 */for (int t = 0; t < successImageNum; t++){vector<Point3f> tempPointSet;for (int i = 0; i < board_size.height; i++){for (int j = 0; j < board_size.width; j++){/* 假设定标板放在世界坐标系中z=0的平面上 */Point3f tempPoint;tempPoint.x = j * square_size.width;tempPoint.y = i * square_size.height;tempPoint.z = 0;tempPointSet.push_back(tempPoint);}}object_Points.push_back(tempPointSet);}for (int i = 0; i < successImageNum; i++){point_counts.push_back(board_size.width * board_size.height);}/* 开始定标 */Size image_size = image_Seq[0].size();cv::Matx33d intrinsic_matrix;    /*****    摄像机内参数矩阵    ****/cv::Vec4d distortion_coeffs;     /* 摄像机的4个畸变系数:k1,k2,k3,k4*/std::vector<cv::Vec3d> rotation_vectors;                           /* 每幅图像的旋转向量 */std::vector<cv::Vec3d> translation_vectors;                        /* 每幅图像的平移向量 */int flags = 0;flags |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC;flags |= cv::fisheye::CALIB_CHECK_COND;flags |= cv::fisheye::CALIB_FIX_SKEW;fisheye::calibrate(object_Points, corners_Seq, image_size, intrinsic_matrix, distortion_coeffs, rotation_vectors, translation_vectors, flags, cv::TermCriteria(3, 20, 1e-6));cout << "定标完成!\n";/************************************************************************对定标结果进行评价*************************************************************************/cout << "开始评价定标结果………………" << endl;double total_err = 0.0;                   /* 所有图像的平均误差的总和 */double err = 0.0;                        /* 每幅图像的平均误差 */vector<Point2f>  image_points2;             /****   保存重新计算得到的投影点    ****/cout << "每幅图像的定标误差:" << endl;cout << "每幅图像的定标误差:" << endl << endl;for (int i = 0; i < image_count; i++){vector<Point3f> tempPointSet = object_Points[i];/****    通过得到的摄像机内外参数,对空间的三维点进行重新投影计算,得到新的投影点     ****/fisheye::projectPoints(tempPointSet, image_points2, rotation_vectors[i], translation_vectors[i], intrinsic_matrix, distortion_coeffs);/* 计算新的投影点和旧的投影点之间的误差*/vector<Point2f> tempImagePoint = corners_Seq[i];Mat tempImagePointMat = Mat(1, tempImagePoint.size(), CV_32FC2);Mat image_points2Mat = Mat(1, image_points2.size(), CV_32FC2);for (size_t i = 0; i != tempImagePoint.size(); i++){image_points2Mat.at<Vec2f>(0, i) = Vec2f(image_points2[i].x, image_points2[i].y);tempImagePointMat.at<Vec2f>(0, i) = Vec2f(tempImagePoint[i].x, tempImagePoint[i].y);}err = norm(image_points2Mat, tempImagePointMat, NORM_L2);total_err += err /= point_counts[i];cout << "第" << i + 1 << "幅图像的平均误差:" << err << "像素" << endl;fout << "第" << i + 1 << "幅图像的平均误差:" << err << "像素" << endl;}cout << "总体平均误差:" << total_err / image_count << "像素" << endl;fout << "总体平均误差:" << total_err / image_count << "像素" << endl << endl;cout << "评价完成!" << endl;/************************************************************************保存定标结果*************************************************************************/cout << "开始保存定标结果………………" << endl;Mat rotation_matrix = Mat(3, 3, CV_32FC1, Scalar::all(0)); /* 保存每幅图像的旋转矩阵 */fout << "相机内参数矩阵:" << endl;fout << intrinsic_matrix << endl;fout << "畸变系数:\n";fout << distortion_coeffs << endl;for (int i = 0; i < image_count; i++){fout << "第" << i + 1 << "幅图像的旋转向量:" << endl;fout << rotation_vectors[i] << endl;/* 将旋转向量转换为相对应的旋转矩阵 */Rodrigues(rotation_vectors[i], rotation_matrix);fout << "第" << i + 1 << "幅图像的旋转矩阵:" << endl;fout << rotation_matrix << endl;fout << "第" << i + 1 << "幅图像的平移向量:" << endl;fout << translation_vectors[i] << endl;}cout << "完成保存" << endl;fout << endl;/************************************************************************显示定标结果*************************************************************************/Mat mapx = Mat(image_size, CV_32FC1);Mat mapy = Mat(image_size, CV_32FC1);Mat R = Mat::eye(3, 3, CV_32F);cout << "保存矫正图像" << endl;for (int i = 0; i != image_count; i++){cout << "Frame #" << i + 1 << "..." << endl;//fisheye::initUndistortRectifyMap(intrinsic_matrix,distortion_coeffs,R,intrinsic_matrix,image_size,CV_32FC1,mapx,mapy);fisheye::initUndistortRectifyMap(intrinsic_matrix, distortion_coeffs, R,getOptimalNewCameraMatrix(intrinsic_matrix, distortion_coeffs, image_size, 1, image_size, 0), image_size, CV_32FC1, mapx, mapy);Mat t = image_Seq[i].clone();cv::remap(image_Seq[i], t, mapx, mapy, INTER_LINEAR);string imageFileName;std::stringstream StrStm;StrStm << i + 1;StrStm >> imageFileName;imageFileName += "_d.jpg";imwrite(imageFileName, t);}cout << "保存结束" << endl;/************************************************************************测试一张图片*************************************************************************/if (1){//cout<<"TestImage ..."<<endl;//Mat testImage = imread("a.jpg",1);//fisheye::initUndistortRectifyMap(intrinsic_matrix,distortion_coeffs,R,//    getOptimalNewCameraMatrix(intrinsic_matrix, distortion_coeffs, image_size, 1, image_size, 0),image_size,CV_32FC1,mapx,mapy);//Mat t = testImage.clone();//cv::remap(testImage,t,mapx, mapy, INTER_LINEAR);//imwrite("TestOutput.jpg",t);//cout<<"保存结束"<<endl;cout << "TestImage ..." << endl;Mat distort_img = imread("a.jpg", 1);Mat undistort_img;Mat intrinsic_mat(intrinsic_matrix), new_intrinsic_mat;intrinsic_mat.copyTo(new_intrinsic_mat);//调节视场大小,乘的系数越小视场越大new_intrinsic_mat.at<double>(0, 0) *= 0.5;new_intrinsic_mat.at<double>(1, 1) *= 0.5;//调节校正图中心,建议置于校正图中心new_intrinsic_mat.at<double>(0, 2) = 0.5 * distort_img.cols;new_intrinsic_mat.at<double>(1, 2) = 0.5 * distort_img.rows;fisheye::undistortImage(distort_img, undistort_img, intrinsic_matrix, distortion_coeffs, new_intrinsic_mat);imwrite("output.jpg", undistort_img);cout << "保存结束" << endl;}return 0;
}

原图:












效果图。

根据自己的视场角实际调整。该纠偏后图片还是有点问题,可以进一步调整,得到更加效果。

3.鱼眼摄像机纠正,相机纠偏,详细源码及讲解相关推荐

  1. Cesium 键盘鼠标控制相机漫游(源码+原理讲解)

    Cesium 键盘鼠标控制相机漫游(源码+原理讲解) 在各大博客平台上,Cesium使用键盘控制相机漫游的源码已经有不少人贴出源码,本人在浏览这些源码的过程中发现大家采用的方式基本一致,大部分代码都是 ...

  2. 双目相机标定OpenCV源码讲解

    双目相机标定OpenCV源码讲解 背景介绍 所述内容 参考资料 摄像机标定部分代码 代码思路 代码中的其他函数 找角点&求内参 求外参 求矫正映射矩阵 后记 背景介绍 暑假接近两个月的时间做了 ...

  3. 基于stm32、0.96寸OLED实现的贪吃蛇小游戏(详细源码注释)

    简介:本实验基于stm32最小系统.0.96寸OLED(68*128)和摇杆实现一个经典的贪吃蛇小游戏.项目源码地址:点击下载. 硬件设计: 普通摇杆,0.96寸OLED 单色屏幕(SPI协议通讯), ...

  4. 基于stm32、0.96寸OLED实现的俄罗斯方块小游戏(详细源码注释)

    概述:本实验基于stm32最小系统.0.96寸OLED(68*128)和摇杆实现一个经典的俄罗斯方块小游戏.项目源码地址:点击下载. 硬件要求: 普通摇杆,两个电位器和一个开关组成,左右摇动控制一个电 ...

  5. 实战|Python轻松实现动态网页爬虫(附详细源码)

    用浅显易懂的语言分享爬虫.数据分析及可视化等干货,希望人人都能学到新知识. 项目背景 事情是这样的,前几天我公众号写了篇爬虫入门的实战文章,叫做<实战|手把手教你用Python爬虫(附详细源码) ...

  6. JUC.Condition学习笔记[附详细源码解析]

    JUC.Condition学习笔记[附详细源码解析] 目录 Condition的概念 大体实现流程 I.初始化状态 II.await()操作 III.signal()操作 3个主要方法 Conditi ...

  7. android 自定义相机源码,Android 自定义相机及分析源码

    Android 自定义相机及分析源码 使用Android 系统相机的方法: 要想让应用有相机的action,咱们就必须在清单文件中做一些声明,好让系统知道,如下 action的作用就是声明action ...

  8. set在python中的用法_python中set的用法:详细源码示例

    这篇文章主要为大家详细介绍了python中set的用法:详细源码示例,具有一定的参考价值,可以用来参考一下. set函数基本用法感兴趣的小伙伴,下面一起跟随512笔记的小编罗X来看看吧. python ...

  9. beautifulsoup解析动态页面div未展开_实战|Python轻松实现动态网页爬虫(附详细源码)...

    用浅显易懂的语言分享爬虫.数据分析及可视化等干货,希望人人都能学到新知识.项目背景事情是这样的,前几天我公众号写了篇爬虫入门的实战文章,叫做<实战|手把手教你用Python爬虫(附详细源码)&g ...

最新文章

  1. 还是自己写的东西比较放心
  2. jexus php 重写,如何让我们的PHP在Jexus中跑起来
  3. 【c++】0.C++笔记
  4. 【小白学PyTorch】15.TF2实现一个简单的服装分类任务
  5. Java获取并输出两日期间的所有日期 .
  6. SQLSERVER和ORACLE批量处理表名和字段名大写
  7. java future用法_纯干货:Java学习过程中的21个知识点和技术点
  8. 奥鹏计算机基础18秋在线作业答案,18秋华师《计算机基础》在线作业1(标准答案).doc...
  9. Qt工作笔记-主界面往模式对话框emit信号,有注意的问题
  10. matlab中LMI工具箱函数feasp的用法
  11. NHibernate Profiler使用方法
  12. dell 重装linux系统_U盘装系统开机按哪个键
  13. 中文搜索引擎技术揭密-网络蜘蛛
  14. 画java类图_java UML类图的使用
  15. 从零开始学习SLAM
  16. Rap2 模拟接口 常见规则示例
  17. vray许可服务器信息无名,【1人回答】vray3.6无法获取许可-3D溜溜网
  18. python复杂网络点图可视化_数据分析:R与Python怎么选?
  19. 安装Tomcat步骤
  20. Docker理论与实践(三)

热门文章

  1. 关于Android百度地图API步骑行导航引擎初始化失败以及View空指针异常的问题
  2. flutter 发送验证码
  3. html如何实现立体效果,纯css实现立体摆放图片效果的示例代码
  4. 在此计算机中找不到cad,在此计算机上找不到AutoCAD201x,你需要安装AutoCAD201x才可以安装此语言包CAD安装失败解决方法...
  5. Surv单因素批量生存分析使用 cox批量生存回归分析有点像deseq2的design差异分析designG:\r\2021_1203_geo\GEO-master\GSE11121_survival
  6. uvaoj 11121 Base -2 整数转成负数进制
  7. uva 11121(-2进制)
  8. 列表排序并返回索引_Python成为专业人士笔记–List列表
  9. Tensorflow2.0 复现 NNLM
  10. 【Java】Java学习笔记(2)——Java面向对象基础作业函数题