2

我目前正在尝试纠正立体相机以创建视差图。不幸的是,我无法通过立体声校正步骤,因为我不断收到错误消息

“OpenCV 错误:未知函数中的错误参数,文件 ..\..\..\modules\core\src\matrix.cpp,第 697 行。”

这个过程很复杂,因为我不是校准相机的人,我也无法使用用于录制视频的相机。我得到了所有的校准参数(内在参数、失真系数、旋转矩阵和平移向量)。如您所见,我尝试将它们直接转换为 CvMat 并以这种方式使用它们,但是当我尝试实际使用它们时出现错误。

提前致谢。

CvMat li, lm, ri, rm, r, t, Rl, Rr, Pl, Pr;    

double init_li[3][3] = 
    {   {477.984984743, 0, 316.17458671}, 
    {0, 476.861945645, 253.45073026}, 
    {0, 0 ,1}   };
double init_lm[5] = {-0.117798518453, 0.147554949385, -0.0549082041898, 0, 0};
double init_ri[3][3] = 
    {{478.640315323, 0, 299.957994781}, 
    {0, 477.898896505, 251.665771947}, 
    {0, 0, 1}};
double init_rm[5] = {-0.10884732532, 0.12118405303, -0.0322073237741, 0, 0};
double init_r[3][3] = 
    {{0.999973709051976, 0.00129700728791757, -0.00713435189275776},
    {-0.00132096594266573, 0.999993501087837, -0.00335452397041856}, 
    {0.00712995468519435, 0.00336386001267643, 0.99996892361313}};
double init_t[3] = {-0.0830973040641153, -0.00062704210860633, 1.4287643345188e-005};

cvInitMatHeader(&li, 3, 3, CV_64FC1, init_li);
cvInitMatHeader(&lm, 5, 1, CV_64FC1, init_lm);
cvInitMatHeader(&ri, 3, 3, CV_64FC1, init_ri);
cvInitMatHeader(&rm, 5, 1, CV_64FC1, init_rm);
cvInitMatHeader(&r, 3, 3, CV_64FC1, init_r);
cvInitMatHeader(&t, 3, 1, CV_64FC1, init_t);
cvInitMatHeader(&Rl, 3,3, CV_64FC1);
cvInitMatHeader(&Rr, 3,3, CV_64FC1);
cvInitMatHeader(&Pl, 3,4, CV_64FC1);
cvInitMatHeader(&Pr, 3,4, CV_64FC1);

//frame is a cv::MAT holding the first frame of the video.
CvSize imageSize = frame.size();
imageSize.width /= 2;

//IT BREAKS HERE
cvStereoRectify(&li, &ri, &lm, &rm, imageSize, &r, &t, &Rl, &Rr, &Pl, &Pr);
4

2 回答 2

0

所以,你被c-api咬了吗?你为什么不直接拒绝呢?

尽可能使用 c++ api,不要用旧的(1.0)开始学习 opencv,不推荐使用的 api,拜托!

double init_li[9] = 
    {   477.984984743, 0, 316.17458671, 
    0, 476.861945645, 253.45073026, 
    0, 0 ,1  };
double init_lm[5] = {-0.117798518453, 0.147554949385, -0.0549082041898, 0, 0};
double init_ri[9] = 
    {   478.640315323, 0, 299.957994781, 
    0, 477.898896505, 251.665771947, 
    0, 0, 1};
double init_rm[5] = {-0.10884732532, 0.12118405303, -0.0322073237741, 0, 0};
double init_r[9] = 
    {   0.999973709051976, 0.00129700728791757, -0.00713435189275776,
    -0.00132096594266573, 0.999993501087837, -0.00335452397041856, 
    0.00712995468519435, 0.00336386001267643, 0.99996892361313};
double init_t[3] = {-0.0830973040641153, -0.00062704210860633, 1.4287643345188e-005};

cv::Mat li(3, 3, CV_64FC1, init_li);
cv::Mat lm(5, 1, CV_64FC1, init_lm);
cv::Mat ri(3, 3, CV_64FC1, init_ri);
cv::Mat rm(5, 1, CV_64FC1, init_rm);
cv::Mat r, t, Rl, Rr, Pl, Pr; // note: no initialization needed.

//frame is a cv::MAT holding the first frame of the video.
cv::Size imageSize = frame.size();
imageSize.width /= 2;

//IT won't break HERE
cv::stereoRectify(li, ri, lm, rm, imageSize, r, t, Rl, Rr, Pl, Pr);

// no need ever to release or care about anything
于 2013-03-19T18:10:45.110 回答
0

好的,所以我想出了答案。问题是我只为 Rl、Rr、Pl 和 Pr 初始化了标头,但没有为数据本身分配内存。我能够按如下方式修复它:

double init_Rl[3][3];
double init_Rr[3][3];
double init_Pl[3][4];
double init_Pr[3][4];

cvInitMatHeader(&Rl, 3,3, CV_64FC1, init_Rl);
cvInitMatHeader(&Rr, 3,3, CV_64FC1, init_Rr);
cvInitMatHeader(&Pl, 3,4, CV_64FC1, init_Pl);
cvInitMatHeader(&Pr, 3,4, CV_64FC1, init_Pr);

虽然,我有一个理论,我可能能够使用 cv::stereoRectify 和 cv::Mats 作为参数,这会让生活变得更轻松。我不知道 cv::stereoRectify 是否存在,但似乎许多其他 c 函数的版本都在 cv 命名空间中。如果很难说,我对 OpenCV 很陌生。

于 2013-03-19T17:53:24.367 回答