Update:
Это код, который вызывает CVCalibrateCamera2():
void calibrate(CvMat * object_points, CvMat * image_points, CvMat * intrinsicsMatrix, CvMat * distortionVector){
const int point_count = object_points->rows;
const int image_count = image_points->rows/point_count;
CvMat * const full_object_points = cvCreateMat(image_count * point_count, 3, CV_32FC1);
CvMat * const point_counts = cvCreateMat(image_count, 1, CV_32SC1);
for (int i = 0; i < image_count; i++){
CV_MAT_ELEM(*point_counts, float, i, 0) = point_count;
for (int j = 0; j < point_count; j++){
for (int k = 0; k < 3; k++){
CV_MAT_ELEM(*full_object_points, float, i * point_count + j, k) = CV_MAT_ELEM(*object_points, float, j, k);
}
}
}
cvCalibrateCamera2(full_object_points, image_points, point_counts, cvSize(1, 1), intrinsicsMatrix, distortionVector, NULL, NULL, 0);
}
И это кусок, который собирает значения точек и передает их функции выше:
int main(){
const float points [] [2] = {{0, 0}, {1, 0}, {2, 0}, {3, 0}};
const int image_count = 5;
const int point_count = sizeof (points)/sizeof(points[1]);
CvMat * const object_points = cvCreateMat(point_count, 3, CV_32FC1);
for (int i = 0; i < point_count; i++){
CV_MAT_ELEM(*object_points, float, i, 0) = points[i][0];
CV_MAT_ELEM(*object_points, float, i, 1) = points[i][1];
CV_MAT_ELEM(*object_points, float, i, 2) = 0;
}
CvMat * const image_points = cvCreateMat(image_count * point_count, 2, CV_32FC1);
collectPoints(setup, image_count, point_count, image_points); // See below about this
CvMat * const intrinsicsMatrix = cvCreateMat(3, 3, CV_32FC1);
CvMat * const distortionVector = cvCreateMat(5, 1, CV_32FC1);
calibrate(object_points, image_points, intrinsicsMatrix, distortionVector);
}
В приведенном выше коде collectPoints() - это функция, использующая стороннюю библиотеку (glitter's WiiYourself wiimote библиотека, если это имеет значение). Код ниже, но важно то, что возвращаемые точки имеют значения от -.5 до .5.
void collectPoints(wiimote_setup & setup, const int image_count, const int point_count, CvMat * const image_points){
image_points->rows = image_count * point_count;
image_points->cols = 2;
bool A_pressed = false;
for (int i = 0; i < image_count; i++){
while (true){
setup.remote.RefreshState();
if (setup.remote.Button.A()){
if (!A_pressed){
for (int j = 0; j < point_count; j++){
wiimote_state::ir::dot & dot = setup.remote.IR.Dot[j];
CV_MAT_ELEM(*image_points, float, i * point_count + j, 0) = .5 - dot.X;
CV_MAT_ELEM(*image_points, float, i * point_count + j, 1) = .5 - dot.Y;
cout << dot.X <<", " << dot.Y << "\n";
}
cout << "\n";
cout.flush();
A_pressed = true;
break;
}
} else{
A_pressed = false;
}
}
}
}
Можете ли вы разместить свой код, который вызывает cvCalibrateCamera2, и код, который генерирует точки объекта/точки изображения, которые ему переданы? Это может помочь сузить проблему. – WildCrustacean