2013-04-24 4 views
2

Преследуя эту ошибку всю ночь, пожалуйста, простите любую несогласованность.Ассемблер, выданный OpenCV checkVector() в противном случае действительным вектором <вектор <Point3f>>

Я пытаюсь использовать calibrateCamera() OpenCV для извлечения внутренних и внешних параметров из набора из пятнадцати изображений, на которых указаны точки объекта и точки мира. Из того, что я могу сказать из отладки, я хватаю действительные точки из входных файлов и помещаю их в vector<Point3f>, который сам поместил в другой vector.

я прохожу всю хижину в calibrateCamera(),

double rms = calibrateCamera(worldPoints, pixelPoints, src.size(), intrinsic, distCoeffs, rvecs, tvecs); 

который бросает Assertion failed (ni >= 0) in unknown function, file ...\calibration.cpp, line 3173

Подтягивание этот файл дает нам

static void collectCalibrationData(InputArrayOfArrays objectPoints, 
           InputArrayOfArrays imagePoints1, 
           InputArrayOfArrays imagePoints2, 
           Mat& objPtMat, Mat& imgPtMat1, Mat* imgPtMat2, 
           Mat& npoints) 
{ 
int nimages = (int)objectPoints.total(); 
int i, j = 0, ni = 0, total = 0; 
CV_Assert(nimages > 0 && nimages == (int)imagePoints1.total() && 
    (!imgPtMat2 || nimages == (int)imagePoints2.total())); 

for(i = 0; i < nimages; i++) 
{ 
    ni = objectPoints.getMat(i).checkVector(3, CV_32F); 
    CV_Assert(ni >= 0); 
    total += ni; 
} 
... 

Насколько мне известно, Point3f имеет CV_32F глубину, и я могу видеть хорошие данные в двойном векторе непосредственно перед калибровкой.

Любые идеи, что может случиться здесь? calibrateCamera() требует vector<vector<Point3f>>, как указано http://aishack.in/tutorials/calibrating-undistorting-with-opencv-in-c-oh-yeah/ и документацией; надеюсь, что getMat (i) не будет из-за этого.

Возможно, это было вызвано на vector<vector<Point2f>> точек пикселя сразу после него? У меня было столько ошибок, что я готов что-то поверить.

Edit: Следовательно, документация checkVector() «s не был действительно полезным

int cv::Mat::checkVector (int elemChannels, int depth = -1, bool RequireContinuous = true) const 

returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise 
+0

Может быть, вы могли бы посмотреть на код учебник калибровки для помощи: http://docs.opencv.org/doc/tutorials/calib3d/camera_calibration/camera_calibration.html – FSaccilotto

+0

@FSaccilotto, я побывал там и взяли их указывают на явное выравнивание количества точек мира и точек пикселя перед вызовом. Однако он не учитывает ошибку, которую я вижу. Единственное различие, которое я мог видеть при обработке точек мира, заключалось в объявлении 'vector > objectPoints (1);', я опустил '(1)'. Я не знаю, изменяет ли это каким-то неосязаемым образом. Я не использовал их код явно, потому что были указаны мои соответствия в мире и пикселе, и было бы более отлаживать внешний код. –

+0

Возможно, вы также можете опубликовать свой код, чтобы мы могли его просмотреть ... В прошлый раз, когда у меня была ошибка checkvector, я также тестировал выход перед вызовом функции CV. 'int ni = objectPoints.getMat (i) .checkVector (3, CV_32F);' – FSaccilotto

ответ

-1

Я согласен с FSaccilotto - звоните checkVector и убедитесь, что вы передаете вектор размера п Mat 1x1:{3 channel}, а не вектор Mat 1 x n:{3 channel} или хуже Mat 1 x n:{2 channel}, что и выталкивает MatOfPoint. Обычно это исправляет 90% проблем, связанных с утверждением. Явно объявляю Mat самостоятельно.

Шаблон объекта несколько странный в том, что координаты x y z находятся в каналах не в размерах Мата.

1

Проблема, возможно, в одном из ваших аргументов InputArrayOfArrays (в точках worldPoints точно, если утверждение выбрано из строки, вставленной в ваш вопрос). Mat: s должен отлично работать здесь.

Я решил ту же ошибку утверждения в своем коде, сделав все 3 InputArrayOfArrays (или vector> и vector> в моем случае) векторами одинаковой длины с полностью заполненными записями. Таким образом, моя проблема была в моей архитектуре: мой вектор объектов-объектов содержал пустые записи (хотя существующие данные были действительными), а calibrate.cpp требует, чтобы в любом из 3-х InputArrayOfArrays не было пустых записей. Btw Я использую изображения оттенков серого для калибровки, так что данные одного канала.

В источнике calib3d наиболее вероятной причиной возникновения ошибки бросания является нулевое значение, если вы проверяли соответствие типов данных.Вы можете попробовать двойной проверки действительный входные данные:

1) подсчитать # допустимых калибровочных изображений из выбранной структуры validCalibImages = (int)goodCalibrationImages.size()

2) определяют WorldPoints, как vector<vector<Point3f> > worldPoints

3) ВАЖНО: изменять размер для данных для каждой записи калибровки worldPoints.resize(validCalibImages)

4) заполнение данными, например

for(int k = 0; k < (int)goodCalibImages.size(); k++){ 
for(int i = 0; i < chessboardSize.height; i++){ 
for(int j = 0; j < chessboardSize.width; j++){ 
       objectPoints[k].push_back(Point3f(i*squareSize, j*squareSize, 0)); 
      } 
     } 
    } 

' Надеюсь, это поможет!

Смежные вопросы