Я пытаюсь получить 3D-координаты нескольких точек в пространстве, но получаю нечетные результаты как от undistortPoints()
, так и от triangulatePoints()
.OpenCV undistortPoints и triangulatePoint дают нечетные результаты (стерео)
Поскольку обе камеры имеет различное разрешение, я откалиброван их по отдельности, получил RMS ошибки в 0,34
и 0,43
, затем использовал stereoCalibrate()
, чтобы получить больше матриц, получил RMS из 0,708
, а затем использовал stereoRectify()
, чтобы получить оставшиеся матрицы. С этим я начал работу над собранными координатами, но получаю странные результаты.
Например, вход: (935, 262)
, а undistortPoints()
выход (1228.709125, 342.79841)
для одной точки, а для другого это (934, 176)
и (1227.9016, 292.4686)
соответственно. Что странно, потому что обе эти точки очень близки к середине кадра, где искажения являются наименьшими. Я не ожидал, что он переместит их на 300 пикселей.
При переходе на traingulatePoints()
результаты становятся еще более странными - я измерил расстояние между тремя точками в реальной жизни (с линейкой) и вычислил расстояние между пикселями на каждом снимке. Поскольку на этот раз точки были на довольно плоской плоскости, эти две длины (пиксель и реальность) соответствовали, как в | AB |/| BC | в обоих случаях было около 4/9. Однако triangulatePoints()
дает мне результаты с рельсов, с | AB |/| BC | 3/2 или 4/2.
Это мой код:
double pointsBok[2] = { bokList[j].toFloat()+xBok/2, bokList[j+1].toFloat()+yBok/2 };
cv::Mat imgPointsBokProper = cv::Mat(1,1, CV_64FC2, pointsBok);
double pointsTyl[2] = { tylList[j].toFloat()+xTyl/2, tylList[j+1].toFloat()+yTyl/2 };
//cv::Mat imgPointsTyl = cv::Mat(2,1, CV_64FC1, pointsTyl);
cv::Mat imgPointsTylProper = cv::Mat(1,1, CV_64FC2, pointsTyl);
cv::undistortPoints(imgPointsBokProper, imgPointsBokProper,
intrinsicOne, distCoeffsOne, R1, P1);
cv::undistortPoints(imgPointsTylProper, imgPointsTylProper,
intrinsicTwo, distCoeffsTwo, R2, P2);
cv::triangulatePoints(P1, P2, imgWutBok, imgWutTyl, point4D);
double wResult = point4D.at<double>(3,0);
double realX = point4D.at<double>(0,0)/wResult;
double realY = point4D.at<double>(1,0)/wResult;
double realZ = point4D.at<double>(2,0)/wResult;
Углы между точками являются своего рода Сорта хорошо, но, как правило, нет:
`7,16816 168,389 4,44275` vs `5,85232 170,422 3,72561` (degrees)
`8,44743 166,835 4,71715` vs `12,4064 158,132 9,46158`
`9,34182 165,388 5,26994` vs `19,0785 150,883 10,0389`
Я пытался использовать undistort()
на весь кадр, но получил результаты так же странно. Расстояние между B и C точек должны быть в значительной степени неизменным во все времена, и все же это то, что я получаю:
7502,42
4876,46
3230,13
2740,67
2239,95
кадр за кадром.
Pixel расстояние (внизу) в зависимости от реального расстояния (вверху) - должно быть очень похоже:
Угол обзор:
Кроме того, следует не как undistortPoints()
и undistort()
дает то же самое результаты (другой набор видео здесь)?
Не могли бы вы включить код, который вы использовали для калибровки, и некоторые образцы изображений для части триангуляции? – AldurDisciple
Это может быть сложно ... там много. Я постараюсь опубликовать только соответствующие части завтра – Petersaber
Это похоже на испорченную калибровку - если вы используете 'undistort' на изображении только с одной камеры (игнорируя стерео калибровку), это работает? Вы должны иметь возможность откалибровать внутреннюю характеристику каждой камеры в отдельности и убедиться, что они в порядке, а затем передать эти значения в стереокалькуляцию в качестве первоначальной догадки с использованием флага 'CV_CALIB_USE_INTRINSIC_GUESS'. – abarry