Проблема калибровки OpenCV

Я работаю над проектом OpenCV и приступаю к калибровке. Я считаю, что я правильно реализовал код; однако я получаю разные значения для матрицы камеры, иногда сильно меняющиеся. После 6 повторений показа калибровочного шаблона 10 раз, я получаю (десятичные дроби для ясности усечены):

[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]

Эти значения отличаются на недопустимые суммы. Мне нужно с достаточной степенью точности знать, что это за параметры. Какова обычно причина этих больших неточностей и как я могу оценить правильность данной матрицы? Кажется, это зависит от разнообразия расстояний и ориентаций, с которых я показываю шаблон, но я не могу понять смысл шаблона.

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

8

Решение

Зависит от камеры / объектива и требуемой точности, но вам, вероятно, потребуется более 10 позиций, и вам нужно охватить более широкий диапазон углов обзора.

Я предполагаю, что 800×600 — это веб-камера с простым широкоугольным объективом с большим количеством искажений. Я бы сказал, что вам нужно 6-8 положений / поворотов цели в каждом из 3-4 различных углов камеры. Вы также должны убедиться, что цель и камера зафиксированы и не двигаются во время изображения. Опять же, предполагая, что камера имеет простое автоматическое усиление, вы должны убедиться, что цель очень хорошо освещена, поэтому она будет использовать высокую скорость затвора и низкое усиление.

Одна из проблем, связанных с техникой, используемой openCV, заключается в том, что ей нужно видеть все углы / точки на цели, чтобы фрейм был идентифицирован и использован в решении — поэтому довольно сложно найти точку рядом с углами изображения. Вам следует проверить данные по количеству изображений, фактически использованных при калибровке — возможно, он лишь находит все точки на нескольких из 10 изображений и основывает решение на этом подмножестве.

5

Другие решения

Также важно не брать только рисунки, перпендикулярные камере, а вращать их. Чтобы улучшить качество результатов, вы также можете внимательно проверить положение обнаруженных углов, удалить снимки, где некоторые углы были обнаружены неправильно, и снова запустить алгоритм.

Я не знаю, какую камеру вы используете, но с камерами, которые страдают от сильных искажений и недостаточно острых, углы могут быть трудно обнаружить правильно. Калибровка OpenCV также может быть реализована с помощью круговой схемы, которая дает лучшие результаты в этом случае.

3

Исходя из моего опыта, вам следует выполнять калибровку с использованием неискаженных изображений с помощью функции undistort (), предоставляемой OpenCV.

Это означает, что вы дважды запускаете калибровку, чтобы определить коэффициенты объектива. Затем не искажайте каждую шахматную раму во втором заезде. Фокусные расстояния fx и fy становятся более точными при использовании неискаженных калибровочных кадров.

1

по словам Чжэнъю Чжана, правильный угол составляет менее 45 градусов, и должно быть более 6 изображений, для них лучше взять 20. Также вам необходимо обратить внимание на световой баланс, интенсивность.

0