Подтверждение, выданное OpenCV checkVector () для действительного вектора & lt; vector & lt; Point3f & gt; & gt;

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

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

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

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

Редактировать:
Как следствие, checkVector()документация была не очень полезна

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

2

Решение

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

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

В источнике 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));
}
}
}


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

1

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

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

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

-1