所以我需要在C ++中使用OpenCV的帮助
基本上我有一个具有一些径向失真的相机,我可以使用OpenCV中提供的示例/示例来取消它。
但是目前我每次运行程序时都必须重新校准相机。但该示例生成XML文件的原因是正确的......要使用这些值...
我的问题是我不确定哪些值以及如何使用XML文件中的这些值来解除相机的影响而无需再次进行整个校准。
我尝试在网上找到这种用法的例子,但出于某种原因,没有任何与我的问题有关的问题......
据说我们应该能够从输出XML文件中获取值并直接在程序中使用它们,这样我们就不必每次都重新校准摄像机。
但目前这正是我的计划所做的:/
我真的希望有人能帮助我
非常感谢 :)
首先,您必须使用XML文件中的Camera Matrix值创建Camera Matrix。
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创建Distortion Matrix。
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方法。
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用于非失真。如果你得到这两个矩阵,你不必每次都重新校准。只需使用重映射和失真即可。
Imgproc.remap(mat, undistortPicture, map1, map2, Imgproc.INTER_LINEAR);
请参阅this链接。
好吧,所以我能够从输出xml文件中提取我认为必要的4件事。基本上我创建了一个名为CalibSet的新类,只是通过“tfs [”“] >> xxx从xml文件中提取数据;”在代码的底部。
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中
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
确保拍摄的照片方向与后面使用的照片方向完全相同(包括垂直或水平镜像)非常重要,否则在使用“undistort”后图像仍然会失真
在此之后,我可以按预期获得未失真的图像但是帧速率非常低(大约10-20FPS)并且如果可能的话,我会感谢任何帮助优化过程;允许来自实时摄像机馈送的更高帧速率