Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv 分解投影矩阵给出了意外的结果_Opencv - Fatal编程技术网

Opencv 分解投影矩阵给出了意外的结果

Opencv 分解投影矩阵给出了意外的结果,opencv,Opencv,我有以下投影矩阵p: -375 0 2000 262500 -375 2000 0 262500 -1 0 0 700 该投影矩阵以px(1px等于0.5mm)在探测器上以mm为单位投影3D点,并根据关系p=K[R | t](其中R是旋转矩阵,t是平移向量)从内在矩阵K[R | t]构建 2000 0 375 0 0 1 0 K = 0 2000 375

我有以下投影矩阵
p

-375   0    2000  262500
-375  2000    0   262500
 -1    0      0    700
该投影矩阵以px(1px等于0.5mm)在探测器上以mm为单位投影3D点,并根据关系
p=K[R | t]
(其中
R
是旋转矩阵,
t
是平移向量)从内在矩阵
K[R | t]
构建

     2000    0    375             0   0   1              0
K =    0   2000   375       R =   0   1   0        t =   0
       0     0     1             -1   0   0             700
出于某些原因,我需要将
p
分解回这些矩阵。当我使用分解投影矩阵时,我将其作为旋转矩阵:

 0   0   0
 0   0   0
-1   0   0
在我看来,它不像旋转矩阵

此外,当我从开放CV分解中构建投影矩阵时,我得到以下矩阵:

-375   0      0   262500
-375   0      0   262500
 -1    0      0    700
看起来很相似,但不一样

我想知道我是做错了什么,还是运气不好,这是这个函数失败的罕见案例之一


请注意,我自己进行了分解,得到了一致的结果,但我更愿意尽可能多地使用开放CV函数。

问题似乎在于
分解投影矩阵所使用的RQ分解。
即使矩阵
P
的第一个平方是非奇异的,
RQDecomp3x3
函数给出了不正确的结果:

    0   0  375              0  0  0
R = 0   0  375         Q =  0  0  0
    0   0   1              -1  0  0
因此,一种解决方法是使用基于以下内容的自制函数(这里是用Python编写的):

我使用反单位矩阵
Q
来构建非传统的Cholesky分解
U*
,其中
U
是上三角。 这种方法与Peter Sturm的方法略有不同,因为我们使用的是关系
P=K[R | t]
,而在Peter Sturm的讲座中使用的是关系
P=K[R |-Rt]

     2000    0    375             0   0   1              0
K =    0   2000   375       R =   0   1   0        t =   0
       0     0     1             -1   0   0             700

一个只使用开放式CV的C++实现更为棘手,因为它们没有真正暴露Cholesky分解的函数:

void chol(cv::Mat const& S, cv::Mat& L)
{
    L = cv::Mat::zeros(S.rows, S.rows, cv::DataType<double>::type);
    for (int i = 0; i < S.rows; ++i) {
        for (int j = 0; j <= i ; ++j) {
            double sum = 0;
            for (int k = 0; k < j; ++k)
                sum += L.at<double>(i,k) * L.at<double>(j,k);
            L.at<double>(i,j) = (i == j) ? sqrt(S.at<double>(i,i) - sum) : (S.at<double>(i,j) - sum) / L.at<double>(j,j);
        }
    }
}

void decomposeP(cv::Mat const& P, cv::Mat& K, cv::Mat& R, cv::Mat& t)
{
    cv::Mat M(3, 3, cv::DataType<double>::type);
    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 3; ++j)
            M.at<double>(i, j) = P.at<double>(i ,j);
    cv::Mat Q = cv::Mat::zeros(3, 3, cv::DataType<double>::type);
    Q.at<double>(0, 2) = 1.0;
    Q.at<double>(1, 1) = 1.0;
    Q.at<double>(2, 0) = 1.0;
    cv::Mat O = Q * M * M.t() * Q;
    cv::Mat C;
    chol(O, C);
    cv::Mat B = Q * C * Q;
    K = B / B.at<double>(2,2);
    cv::Mat A = K.inv() * M;
    double l = std::pow((1 / cv::determinant(A)), 1/3);
    R = l * A;
    cv::Mat p(3, 1, cv::DataType<double>::type);
    for (int i = 0; i < 3; ++i)
        p.at<double>(i, 0) = P.at<double>(i ,3);
    t = l * K.inv() * p;
}
void chol(cv::Mat const&S,cv::Mat&L)
{
L=cv::Mat::零(S.rows,S.rows,cv::DataType::type);
对于(int i=0;i对于(int j=0;j你不是得到了0 fx和fy吗?你是从哪里得到这个投影矩阵的?我编辑了我的问题,以提供关于这个投影矩阵起源的更多信息。你可能想用不同的K,R,t值测试你自己的OpenCV分解实现。这样,你就可以确定它是一个边缘情况还是一个缺陷OpenCV。如果您认为此OpenCV函数中存在错误,您还可以检查源代码并打开一个问题。此外,您应该发布OpenCV的源代码,以检查一切是否正常,以及您的实现是否有帮助。