使用OpenCV标定鱼眼镜头(C++)
来源:互联网 发布:缩小手机屏幕的软件 编辑:程序博客网 时间:2024/06/08 20:09
使用OpenCV标定鱼眼镜头(C++)
本人邮箱:sylvester0510@163.com,欢迎交流讨论,
欢迎转载,转载请注明网址http://blog.csdn.net/u010128736/
一、使用的函数
由于鱼眼镜头和针孔镜头的模型不一样,对于鱼眼镜头的模型在之前的博客中已经做了详细介绍,这里直接使用OpenCV中的cv::fisheye::calibrate()函数进行标定。函数原型如下,需要输入目标点集,图像点集、图像尺寸。函数输出相机内参,畸变系数,旋转矩阵和平移向量,以及反投影误差。
CV_EXPORTS double calibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, const Size& image_size, InputOutputArray K, InputOutputArray D, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, int flags = 0, TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON));
二、采集标定图像
采集若干拍摄有标定棋盘格的图像,并使棋盘格出现在画面的各个位置,特别是边缘位置。如下图所示:
三、标定代码
#include "stdio.h"#include <iostream>#include <fstream>#include <io.h>#include "opencv2/opencv.hpp"#include <opencv2/core/core.hpp>#include "opencv2/calib3d/calib3d.hpp"#include <opencv2/highgui/highgui.hpp>using namespace std;using namespace cv;void getFiles(string path, vector<string>& files){ //文件句柄 intptr_t hFile = 0; //文件信息 struct _finddata_t fileinfo; string p; if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1) { do { //如果是目录,迭代之 //如果不是,加入列表 if ((fileinfo.attrib & _A_SUBDIR)) { if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0) getFiles(p.assign(path).append("\\").append(fileinfo.name), files); } else { files.push_back(p.assign(path).append("\\").append(fileinfo.name)); } } while (_findnext(hFile, &fileinfo) == 0); _findclose(hFile); }}int main(int argc, char** argv){ string filePath = ".\\720PPcalib\\front"; vector<string> files; ////获取该路径下的所有文件 getFiles(filePath, files); const int board_w = 6; const int board_h = 4; const int NPoints = board_w * board_h;//棋盘格内角点总数 const int boardSize = 30; //mm Mat image,grayimage; Size ChessBoardSize = cv::Size(board_w, board_h); vector<Point2f> tempcorners; int flag = 0; flag |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC; //flag |= cv::fisheye::CALIB_CHECK_COND; flag |= cv::fisheye::CALIB_FIX_SKEW; //flag |= cv::fisheye::CALIB_USE_INTRINSIC_GUESS; vector<Point3f> object; for (int j = 0; j < NPoints; j++) { object.push_back(Point3f((j % board_w) * boardSize, (j / board_w) * boardSize, 0)); } cv::Matx33d intrinsics;//z:相机内参 cv::Vec4d distortion_coeff;//z:相机畸变系数 vector<vector<Point3f> > objectv; vector<vector<Point2f> > imagev; Size corrected_size(1280, 720); Mat mapx, mapy; Mat corrected; ofstream intrinsicfile("intrinsics_front1103.txt"); ofstream disfile("dis_coeff_front1103.txt"); int num = 0; bool bCalib = false; while (num < files.size()) { image = imread(files[num]); if (image.empty()) break; imshow("corner_image", image); waitKey(10); cvtColor(image, grayimage, CV_BGR2GRAY); IplImage tempgray = grayimage; bool findchessboard = cvCheckChessboard(&tempgray, ChessBoardSize); if (findchessboard) { bool find_corners_result = findChessboardCorners(grayimage, ChessBoardSize, tempcorners, 3); if (find_corners_result) { cornerSubPix(grayimage, tempcorners, cvSize(5, 5), cvSize(-1, -1), cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1)); drawChessboardCorners(image, ChessBoardSize, tempcorners, find_corners_result); imshow("corner_image", image); cvWaitKey(100); objectv.push_back(object); imagev.push_back(tempcorners); cout << "capture " << num << " pictures" << endl; } } tempcorners.clear(); num++; } cv::fisheye::calibrate(objectv, imagev, cv::Size(image.cols,image.rows), intrinsics, distortion_coeff, cv::noArray(), cv::noArray(), flag, cv::TermCriteria(3, 20, 1e-6)); fisheye::initUndistortRectifyMap(intrinsics, distortion_coeff, cv::Matx33d::eye(), intrinsics, corrected_size, CV_16SC2, mapx, mapy); for(int i=0; i<3; ++i) { for(int j=0; j<3; ++j) { intrinsicfile<<intrinsics(i,j)<<"\t"; } intrinsicfile<<endl; } for(int i=0; i<4; ++i) { disfile<<distortion_coeff(i)<<"\t"; } intrinsicfile.close(); disfile.close(); num = 0; while (num < files.size()) { image = imread(files[num++]); if (image.empty()) break; remap(image, corrected, mapx, mapy, INTER_LINEAR, BORDER_TRANSPARENT); imshow("corner_image", image); imshow("corrected", corrected); cvWaitKey(200); } cv::destroyWindow("corner_image"); cv::destroyWindow("corrected"); image.release(); grayimage.release(); corrected.release(); mapx.release(); mapy.release(); return 0;}
四、标定结果
使用标定的结果进行畸变校正后的结果如下所示,可以看到,原本弯曲的曲线已经变直。
2 0
- 使用OpenCV标定鱼眼镜头(C++)
- 使用OpenCV标定鱼眼镜头(C++)
- 利用OpenCV3进行鱼眼镜头标定
- 鱼眼镜头的标定及矫正
- 使用OpenCV进行标定(Python)
- 使用OpenCV进行标定(Python)
- OpenCV使用标定图
- 鱼眼镜头的分类
- 鱼眼镜头的选型
- 使用OpenCV进行摄像机标定
- 使用OpenCV进行摄像机标定
- 使用OpenCV进行摄像机标定
- 使用opencv标定双目摄像头
- 张正友相机标定算法原理与源代码(OpenCV+C++)
- 基于matlab标定数据,使用opencv实现双目立体摄像头的标定(源代码)
- 基于matlab标定数据,使用opencv实现双目立体摄像头的标定(源代码)
- 使用opencv标定单目相机(张正友法)代码实现
- 鱼眼镜头畸变校正模型
- Hibernate二级缓存
- 嵌入式linux软件平台--uboot引导流程
- CSDN_C_IDE下修改运行oracle_SCTP_样例
- 线程中的wait和notify方法
- mvc 结构设计浅析
- 使用OpenCV标定鱼眼镜头(C++)
- ubuntu 上安装hadoop2.4.1
- JS、Jquery实现---把后台传过来的时间毫秒数转换成想要的日期格式
- Android studio 设置之修改背景颜色为护眼色
- GPS 定位经纬度
- 双向链表
- Linux笔记(第5,6,7章)
- jsonp其实很简单【ajax跨域请求】
- 使用 全连接神经网络 和 词袋模型 进行文本分类的example