2015-07-10 8 views
1

Полная ошибка INT) imagePoints1.total:OpenCV calibrateCamera - утверждение невыполненным (nimages> 0 && nimages == (()

OpenCV Error: Assertion failed (nimages > 0 && nimages == 
(int)imagePoints1.total() && (!imgPtMat2 || nimages == 
(int)imagePoints2.total())) in collectCalibrationData, file C:\OpenCV 
\sources\modules\calib3d\src\calibration.cpp, line 3164 

Код:

cv::VideoCapture kalibrowanyPlik; //the video 

cv::Mat frame; 
cv::Mat testTwo; //undistorted 
cv::Mat cameraMatrix = (cv::Mat_<double>(3, 3) << 2673.579, 0, 1310.689, 0, 2673.579, 914.941, 0, 0, 1); 
cv::Mat distortMat = (cv::Mat_<double>(1, 4) << -0.208143, 0.235290, 0.001005, 0.001339); 
cv::Mat intrinsicMatrix = (cv::Mat_<double>(3, 3) << 1, 0, 0, 0, 1, 0, 0, 0, 1); 
cv::Mat distortCoeffs = cv::Mat::zeros(8, 1, CV_64F); 
//there are two sets for testing purposes. Values for the first two came from GML camera calibration app. 

std::vector<cv::Mat> rvecs; 
std::vector<cv::Mat> tvecs; 
std::vector<std::vector<cv::Point2f> > imagePoints; 
std::vector<std::vector<cv::Point3f> > objectPoints; 

kalibrowanyPlik.open("625.avi"); 
    //cv::namedWindow("Distorted", CV_WINDOW_AUTOSIZE); //gotta see things 
    //cv::namedWindow("Undistorted", CV_WINDOW_AUTOSIZE); 

int maxFrames = kalibrowanyPlik.get(CV_CAP_PROP_FRAME_COUNT);  
int success = 0; //so we can do the calibration only after we've got a bunch 

for(int i=0; i<maxFrames-1; i++) {  
    kalibrowanyPlik.read(frame); 
    std::vector<cv::Point2f> corners; //creating these here so they're effectively reset each time 
    std::vector<cv::Point3f> objectCorners; 

    int sizeX = kalibrowanyPlik.get(CV_CAP_PROP_FRAME_WIDTH); //imageSize 
    int sizeY = kalibrowanyPlik.get(CV_CAP_PROP_FRAME_HEIGHT); 

    cv::cvtColor(frame, frame, CV_BGR2GRAY); //must be gray 

    cv::Size patternsize(9,6); //interior number of corners 

    bool patternfound = cv::findChessboardCorners(frame, patternsize, corners, cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_NORMALIZE_IMAGE + cv::CALIB_CB_FAST_CHECK); //finding them corners 

    if(patternfound == false) { //gotta know 
     qDebug() << "failure"; 
    } 
    if(patternfound) { 
     qDebug() << "success!"; 
      std::vector<cv::Point3f> objectCorners; //low priority issue - if I don't do this here, it becomes empty. Not sure why. 
      for(int y=0; y<6; ++y) { 
       for(int x=0; x<9; ++x) { 
        objectCorners.push_back(cv::Point3f(x*28,y*28,0)); //filling the array 
       } 
      } 

      cv::cornerSubPix(frame, corners, cv::Size(11, 11), cv::Size(-1, -1), 
      cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1)); 

      cv::cvtColor(frame, frame, CV_GRAY2BGR); //I don't want gray lines 

      imagePoints.push_back(corners); //filling array of arrays with pixel coord array 
      objectPoints.push_back(objectCorners); //filling array of arrays with real life coord array, or rather copies of the same thing over and over 
      cout << corners << endl << objectCorners; 
      cout << endl << objectCorners.size() << "___" << objectPoints.size() << "___" << corners.size() << "___" << imagePoints.size() << endl; 
      cv::drawChessboardCorners(frame, patternsize, cv::Mat(corners), patternfound); //drawing. 

      if(success > 5) { 
       double rms = cv::calibrateCamera(objectPoints, corners, cv::Size(sizeX, sizeY), intrinsicMatrix, distortCoeffs, rvecs, tvecs, cv::CALIB_USE_INTRINSIC_GUESS); 
//error - caused by passing CORNERS instead of IMAGEPOINTS. Also, imageSize is 640x480, and I've set the central point to 1310... etc 
       cout << endl << intrinsicMatrix << endl << distortCoeffs << endl; 
       cout << "\nrms - " << rms << endl; 
      } 
      success = success + 1; 

     //cv::imshow("Distorted", frame); 
     //cv::imshow("Undistorted", testTwo); 
     } 
    } 

Я сделал немногочисленное чтение (This was an especially informative read), в том числе более дюжины потоков, сделанных здесь в StackOverflow, и все, что я обнаружил, заключается в том, что эта ошибка создается либо неравномерными изображениями и объектными точками, либо путем их частичной нулевой или пустой или нулевой (и ссылки на учебные пособия, которые 't help). Ничего из этого не происходит - вывод из .size() chec К является:

54___7___54___7 

Для objectCorners (реальные жизненные координат), objectPoints (количество массивов вставлены) и то же самое для углов (пиксель Coords) и imagePoints. Они не пустые, выход:

(...) 
277.6792, 208.92903; 
241.83429, 208.93048; 
206.99866, 208.84637; 
(...) 
84, 56, 0; 
112, 56, 0; 
140, 56, 0; 
168, 56, 0; 
(...) 

Образец рамки: enter image description here

Я знаю, что это беспорядок, но до сих пор я пытаюсь выполнить код, а не получить точный чтение.

Каждый из них имеет ровно 54 строки. Кто-нибудь есть идеи о том, что вызывает ошибку? Я использую OpenCV 2.4.8 и Qt Creator 5.4 в Windows 7.

+0

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

+0

К сожалению, это должно быть видео. Я включу фрейм в OP – Petersaber

+1

Возможно, установите контрольную точку на drawChessboardCorners, проверьте, имеют ли элементы в объектных точках и углах одинаковый размер. –

ответ

1

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

В большинстве случаев (если не все) размер < = 25 достаточно, чтобы получить хороший результат. Фокусное расстояние около 633 не является wierd, это означает, что фокусное расстояние составляет 633 * размер датчика. Размер CCD или CMOS должен находиться где-то в ИНСТРУКЦИЯх вместе с вашей камерой. Узнайте, раз 633, результатом будет ваше фокусное расстояние.

Одно предложение уменьшить количество используемых изображений: используя изображения, сделанные с разных точек зрения. 10 изображений с 10 разных точек зрения приносят гораздо лучший результат, чем 100 изображений из тех же (или поблизости) точек зрения. Это одна из причин, по которой видео не является хорошим вкладом. Я думаю, что с вашим кодом все изображения, переданные в calibratecamera, могут быть с близлежащих точек зрения.Если это так, точность калибровки ухудшается.

+0

Отличный ответ. Я изменю свой код соответственно. К сожалению, это должен быть видео ... Я думаю, что я просто добавлю инструмент, который позволит пользователю выбирать определенные кадры (или, скорее, искать их по выбранным временным меткам), и заставить его выбрать 10-15, покрывая весь экран с разных точек зрения и сохранить результаты в файле XML. 633 * 1/2,5, преобразованный из дюймов, равен 2532, который нигде не приближается к 4620 (наиболее точные результаты) или 5800 (фокусное расстояние, заданное manafacturer). Ну что ж. Я буду откалибровать. – Petersaber