我有一个(x,y)点,一个3x3相机矩阵和4个失真系数,我希望得到无失真点。我的代码看起来像这样......
double distorted_point_x = 10;
double_distorted_point_y = 20;
Emgu.CV.Matrix<double> distorted_point = new Emgu.CV.Matrix<double>(new double[,] {{distorted_point_x,distorted_point_y}});
Emgu.CV.Matrix<double> undistorted_point = new Emgu.CV.Matrix<double>(new double[,] {{-1,-1}}); // init to -1
Emgu.CV.Matrix<double> distortion_coefficients = new Matrix<double>(new double[] {0,0,0,0});
Emgu.CV.Matrix<double> camera_matrix = new Matrix<double>(new double[,] {{0,0,0},{0,0,0},{0,0,0}});
// copy the stuff; there's probably a more elegant way to copy but this works
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
camera_matrix[row, col] = my_calibrated_camera_matrix[row, col];
}
}
CvInvoke.UndistortPoints(distorted_point, undistorted_point, camera_matrix, distortion_coefficients);
undistorted_point_x = undistorted_point[0, 0];
undistorted_point_y = undistorted_point[0, 1];
当我运行(VS2010)时,我将此异常转储到异常日志文件中:
UnhandledException: OpenCV: CV_IS_MAT(_src) && CV_IS_MAT(_dst) &&
(_src->rows == 1 || _src->cols == 1) && (_dst->rows == 1 || _dst->cols
== 1) && _src->cols + _src->rows - 1 == _dst->rows + _dst->cols - 1 &&
(CV_MAT_TYPE(_src->type) == CV_32FC2 || CV_MAT_TYPE(_src->type) ==
CV_64FC2) && (CV_MAT_TYPE(_dst->type) == CV_32FC2 ||
CV_MAT_TYPE(_dst->type) == CV_64FC2)
我有来自opencv的undistort.cpp,我知道这来自cvUndistortPoints()中的CV_ASSERT。我想知道它是否在CV_MAT_TYPE()测试中进行了轰炸,看起来它期望矩阵有2个通道。 (当输入不是图像数据时,为什么会这样?)如果它确实需要是2通道,我如何在Matrix中指定?我尝试使用Mat,但我不知道如何初始化Mat的内容。我非常感谢任何指针。感谢。
答案 0 :(得分:1)
cvUndistortPoints方法要求矩阵类型CV_32FC2
或CV_64FC2
您可以使用带有显式通道编号
的矩阵构造函数创建它var rows = 1;
var cols = 1;
var channels = 2;
var distorted_point = new Matrix<double>(rows, cols, channels)
{
Data =
{
[0, 0] = distorted_point_x,
[0, 1] = distorted_point_y
}
};
var undistorted_point = new Matrix<double>(rows, cols, channels)
{
Data =
{
[0, 0] = -1,
[0, 1] = -1
}
};
如果您不需要double
精度,可以使用
var distorted_point = new VectorOfPointF(new[] { new PointF(10, 20) });
var undistorted_point = new VectorOfPointF(new[] { new PointF(-1, -1) });
最后相机矩阵应该是
var camera_matrix = new Matrix<double>(3, 3);
答案 1 :(得分:0)
我也遇到了这个问题,我花了一些时间来研究最终的理解。 您会看到上面的公式,在开放系统中,扭曲操作在相机矩阵之前,因此处理顺序为: image_distorted-> camera_matrix->取消扭曲功能-> camera_matrix->返回image_undistorted。
因此,您需要再次修复和camera1。
std::tie(x, y, z) = std::make_tuple(y, z, x);
否则,如果最后两个参数为空,则将其投影到归一化图像坐标。
查看代码:opencv-3.4.0-src \ modules \ imgproc \ src \ undistort.cpp:297 cvUndistortPointsInternal() 公式