关于C#:相机校准数据检索

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);

请参阅此链接。