我正在研究一个OpenCV项目,并且要进行校准。我相信我已经正确实现了代码;但是我得到的相机矩阵值不同,有时会有很大的差异。在重复显示10次校准图案6次之后,我得到了(为清楚起见,小数点被截断了):

[573, 0,  386;
  0, 573, 312;
  0,  0,   1]

[642, 0,  404;
  0, 644, 288;
  0,  0,   1]

[664, 0,  395;
  0, 665, 272;
  0,  0,   1]

[629, 0,  403;
  0, 630, 288;
  0,  0,   1]

[484, 0,  377;
  0, 486, 307;
  0,  0,   1]

[644, 0,  393;
  0, 643, 289;
  0,  0,   1]

这些值相差 Not Acceptable 数量。我需要相当准确地知道给定的参数是什么。通常,造成这些较大误差的原因是什么?如何评估给定矩阵的正确性?这似乎取决于我显示图案的距离和方向的变化,但我无法理解该图案。

代码:
using namespace cv;
using namespace std;

int main(int, char**)
{
    VideoCapture cap(1);
    if(!cap.isOpened())
        return -1;

    cap.set(CV_CAP_PROP_FRAME_WIDTH,800);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT,600);
    Mat edges;
    Size size(9,17);

    int counter = 10;

    vector<Point2f> corners;
    bool found;

    vector<Point3f> chess = fr::ChessGen::getBoard(size,1,true);

    vector<vector<Point3f> > objectPoints;
    vector<vector<Point2f> > imagePoints;

    Mat camera = Mat::eye(3,3,CV_64F);
    Mat distortion = Mat::zeros(8, 1, CV_64F);
    vector<Mat > rvecs;
    vector<Mat > tvecs;

    namedWindow("edges",1);
    for(;;)
    {
        Mat frame;
        cap >> frame;
        cvtColor(frame, edges, CV_BGR2GRAY);

        found = findCirclesGrid(edges,size,corners
                                ,CALIB_CB_ASYMMETRIC_GRID
                                );
        if(found) frame.convertTo(edges,-1,0.2);

        drawChessboardCorners(edges,size,corners,found);

        imshow("edges", edges);
        if(found){
            if(waitKey(200)>=0){
                objectPoints.push_back(chess);
                imagePoints.push_back(corners);
                if(--counter<= 0)
                    break;
            }
        }
        else waitKey(30);
    }

    calibrateCamera(objectPoints,imagePoints,Size(800,600),camera,distortion,rvecs,tvecs,0);

    if(found) imwrite("/home/ryan/snapshot.png",edges);

    cout << camera << endl;

    return 0;
}

最佳答案

取决于相机/镜头和所需的精度,但是您可能需要10个以上的位置,并且需要覆盖更大的视角范围。

我从800x600假设这是一个带有简单广角镜且失真很多的网络摄像头。我要说的是,您需要相对于相机以3-4个不同的角度分别对目标进行6-8个位置/旋转。您还需要确保目标和相机固定在图像中并且不会移动。再次假设相机具有简单的自动增益,则应确保目标照明良好,因此将使用较快的快门速度和较低的增益。

openCV使用的技术的一个问题是,它需要查看目标上的所有角/点才能识别并在解决方案中使用该框架-因此很难在图像的角附近获取点。您应该检查数据以了解校准中实际使用的图像数量-可能只是在10张图像中的所有图像上找到所有点,然后将解决方案基于该子集。

关于c++ - OpenCV校准问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13637759/

10-12 21:53