opencv矩阵Pseudo Inverse失败

时间:2016-11-25 08:40:18

标签: c++ opencv

我找到了pinv() example并成功运行。

但是我的版本失败了:

Mat1b B = Mat(400, 10, CV_32FC1);
for (r = 0; r < 20; r++)
{
    for (c = 0; c < 20; c++)
    {
        B(n,0) = 1;
        B(n,1) = r;
        B(n,2) = c;
        B(n,3) = r*r;
        B(n,4) = c*r;
        B(n,5) = c*c;
        B(n,6) = r*r*r;
        B(n,7) = c*r*r;
        B(n,8) = c*c*r;
        B(n,9) = c*c*c;
        n = n + 1;
    }
}
Mat1b Bpinv = Mat(10, 400, CV_32FC1);
invert(B, Bpinv, DECOMP_SVD);

invert中的错误是:

  

这样的错误信息:OpenCV错误:断言失败(在= cv :: invert中键入== CV_32F || type == CV_64F)。

看起来CV_32FCV_64F之间发生了一些冲突,但我根本没有使用CV_64F格式。怎么会发生这种情况?

2 个答案:

答案 0 :(得分:1)

您使用的是Mat1b(即Mat_<uchar>类型CV_8UC1},但它应为Mat1f(即Mat_<float>类型CV_32FC1)或Mat1d(即Mat_<double>类型CV_64FC1

您可以看到CV_8U既不是CV_32F也不是CV_64F。请注意,支票仅限于深度而非通道数。

所以使用Mat_<Tp>的正确代码是(Mat1fMat1d):

Mat1f B(400, 10);
for (r = 0; r < 20; r++)
{
    for (c = 0; c < 20; c++)
    {
        B(n,0) = 1;
        B(n,1) = r;
        B(n,2) = c;
        B(n,3) = r*r;
        B(n,4) = c*r;
        B(n,5) = c*c;
        B(n,6) = r*r*r;
        B(n,7) = c*r*r;
        B(n,8) = c*c*r;
        B(n,9) = c*c*c;
        n = n + 1;
    }
}

// You don't have to initialize 'OutputArray' for OpenCV functions
Mat1f Bpinv;
invert(B, Bpinv, DECOMP_SVD);

或者,使用Mat

Mat B(400, 10, CV_32FC1);
for (r = 0; r < 20; r++)
{
    for (c = 0; c < 20; c++)
    {
        B.at<float>(n,0) = 1;
        B.at<float>(n,1) = r;
        B.at<float>(n,2) = c;
        B.at<float>(n,3) = r*r;
        B.at<float>(n,4) = c*r;
        B.at<float>(n,5) = c*c;
        B.at<float>(n,6) = r*r*r;
        B.at<float>(n,7) = c*r*r;
        B.at<float>(n,8) = c*c*r;
        B.at<float>(n,9) = c*c*c;
        n = n + 1;
    }
}

// You don't have to initialize 'OutputArray' for OpenCV functions
Mat Bpinv;
invert(B, Bpinv, DECOMP_SVD);

答案 1 :(得分:0)

您使用的是CV_32FC1,而不是CV_32F。查看this answer以查看差异。我认为如果你把它改成CV_32F它应该有效。