Camera calibration data retrieval
因此我需要有关C语言中的OpenCV的帮助
基本上,我的摄像机有一些径向变形,可以使用OpenCV中提供的示例/示例来使其失真。
但是目前,每次运行程序时,我都必须重新校准相机。但是该示例出于某种原因而生成了XML文件...要利用这些值...
我的问题是我不确定哪些值以及如何使用XML文件中的这些值来使相机不失真,而不必再次进行整个校准。
我尝试在线查找这种用法的示例,但由于某种原因,没有出现与我的问题相关的信息...
假定我们应该能够从输出XML文件中获取值,并直接在程序中使用它们,因此我们不必每次都重新校准摄像机。
但是目前,这正是我的程序正在执行的操作:/
我真的希望有人可以帮助我
非常感谢:)
好的,因此我能够从输出xml文件中提取我认为必要的4件事。本质上,我创建了一个名为CalibSet的新类,并通过代码底部的" tfs ["] >> xxx;"从xml文件中提取了数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | class CalibSet { public: Size Boardsize; // The size of the board -> Number of items by width and height Size image; // image size String calibtime; Mat CamMat; // camera matrix Mat DistCoeff; // distortion coefficient Mat PViewReprojErr; // per view reprojection error float SqSize; // The size of a square in your defined unit (point, millimeter,etc). float avg_reproj_error; int NrFrames; // The number of frames to use from the input for calibration int Flags; bool imagePoints; // Write detected feature points bool ExtrinsicParams; // Write extrinsic parameters bool GridPoints; // Write refined 3D target grid points bool fisheyemodel; // use fisheye camera model for calibration void write(FileStorage& fs) const //Write serialization for this class { fs <<"{" <<"nr_of_frames" << NrFrames <<"image_width" << image.width <<"image_height" << image.height <<"board_width" << Boardsize.width <<"board_height" << Boardsize.height <<"square_size" << SqSize <<"flags" << Flags <<"fisheye_model" << fisheyemodel <<"camera_matrix" << CamMat <<"distortion_coefficients" << DistCoeff <<"avg_reprojection_error" << avg_reproj_error <<"per_view_reprojection_errors" << PViewReprojErr <<"extrinsic_parameters" << ExtrinsicParams <<"}"; } void read(const FileNode& node) //Read serialization for this class { node["calibration_time"] >> calibtime; node["nr_of_frames"] >> NrFrames; node["image_width"] >> image.width; node["image_height"] >> image.height; node["board_width"] >> Boardsize.width; node["board_height"] >> Boardsize.height; node["square_size"] >> SqSize; node["flags"] >> Flags; node["fisheye_model"] >> fisheyemodel; node["camera_matrix"] >> CamMat; node["distortion_coefficients"] >> DistCoeff; node["avg_reprojection_error"] >> avg_reproj_error; node["per_view_reprojection_errors"] >> PViewReprojErr; node["extrinsic_parameters"] >> ExtrinsicParams; } }; CalibSet CS; FileStorage tfs(inputCalibFile, FileStorage::READ); // Read the settings if (!tfs.isOpened()) { cout <<"Could not open the calibration file: "" << inputCalibFile <<""" << endl; return -1; } tfs["camera_matrix"] >> CS.CamMat; tfs["distortion_coefficients"] >> CS.DistCoeff; tfs["image_width"] >> CS.image.width; tfs["image_height"] >> CS.image.height; tfs.release(); // close Settings file |
然后,我使用函数" undistort"来校正存储在帧中的实时摄像机帧,并将校正后的图像放入rframe
中。
1 2 3 | flip(frame, frame, -1); // flip image vertically so that it's not upside down cv::undistort(frame, rframe, CS.CamMat, CS.DistCoeff); flip(rframe, rframe, +1); // flip image horizontally |
重要的是要确保拍摄的照片的方向与以后使用的方向完全相同(包括垂直或水平镜像),否则在使用"扭曲"后图像仍会失真。
在此之后,我可以得到预期的图像,但是帧率极低(大约10-20FPS),如果可以的话,我希望能对优化处理过程有所帮助;以便从实时摄像机的提要中获得更高的帧速率
首先,您必须使用XML文件中的Camera Matrix值创建Camera Matrix。
1 2 3 4 5 6 7 8 9 10 | Mat cameraMatrix = new Mat(new Size(3,3), CvType.CV_64FC1); cameraMatrix.put(0,0,3275.907); cameraMatrix.put(0,1,0); cameraMatrix.put(0,2,2069.153); cameraMatrix.put(1,0,0); cameraMatrix.put(1,1,3270.752); cameraMatrix.put(1,2,1139.271); cameraMatrix.put(2,0,0); cameraMatrix.put(2,1,0); cameraMatrix.put(2,2,1); |
第二,从XML文件中创建具有Distortion_Coefficients的失真矩阵。
1 2 3 4 5 | Mat distortionMatrix = new Mat(new Size(4,1), CvType.CV_64FC1); distortionMatrix.put(0,0,-0.006934); distortionMatrix.put(0,1,-0.047680); distortionMatrix.put(0,2,0.002173); distortionMatrix.put(0,3,0.002580); |
最后,使用OpenCV方法。
1 2 3 4 | Mat map1 = new Mat(); Mat map2 = new Mat(); Mat temp = new Mat(); Imgproc.initUndistortRectifyMap(cameraMatrix, distortionMatrix, temp, cameraMatrix, src.size(), CvType.CV_32FC1, map1, map2); |
您将获得两个矩阵map1,map2,用于不失真。
如果得到这两个矩阵,则不必每次都重新校准。
只需使用remap即可完成不失真。
1 | Imgproc.remap(mat, undistortPicture, map1, map2, Imgproc.INTER_LINEAR); |
请参阅此链接。