如何使用OpenCV执行LU分解? [英] How to perform LU-decomposition with OpenCV?

查看:120
本文介绍了如何使用OpenCV执行LU分解?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

cvInvert()方法采用一个标志CV_LU,它执行LU分解以反转输入矩阵。但是有没有办法获得在此计算过程中形成的L和U矩阵?
为LU分解写一个新函数似乎毫无意义,OpenCV已经为它编写了优化代码。

The cvInvert() method takes a flag CV_LU that does the LU factorisation to invert an input matrix. However is there any way to obtain the L and U matrices that are formed during this computation? Is seems pointless to write a new function for LU-decomposition is OpenCV already has optimized code for it.

推荐答案

不幸的是,它看起来不像OpenCV为您提供了访问L和U矩阵的方法。 此处是该功能的实施方式。并且,出于性能原因,看起来LU分解是就地完成的。所以,你可能需要自己动手。

Unfortunately, it doesn't look like OpenCV gives you a way to access the L and U matrices. Here is how the function is implemented. And, it looks like for performance reasons LU-decomposition is done in-place. So, you will probably have to do it on your own.

编辑:看看Matlab和Eigen如何看待LU -decomposition你可以在cvInvert调用后实际检索它们。 L矩阵是结果的严格下三角矩阵加上Identity矩阵,U矩阵是上三角矩阵。

It appears that after looking at both how Matlab and Eigen do LU-decomposition you can actually retrieve them after the cvInvert call. The L matrix is the strictly lower-triangle matrix of the result plus the Identity matrix, and the U matrix is the upper triangle matrix.

编辑: Eigen 实际上与OpenCV相当完美。而且,它们似乎有一个LU分解类,这里。如果您自己构建,Eigen已经是OpenCV的依赖项,您应该可以使用它(它完全在头文件中实现,因此它非常易于使用)。还有一个OpenCV头实现了特征矩阵和OpenCV矩阵之间的转换@ #include< opencv2 / core / eigen.hpp>

Eigen actually integrates fairly well with OpenCV. And, it appears they have an LU decomposition class implemented here. Eigen is already a dependency for OpenCV if you built it yourself, you should have it available to use (it's completely implemented in header files, so that makes it really easy to use). There is also an OpenCV header implementing the conversion between Eigen matrices and OpenCV matrices @ #include <opencv2/core/eigen.hpp>.

但是,至少在我的SVN版本中,这个标题不能正常工作,所以我自己做了:

However, at least on my SVN build, this header didn't work right, so I made my own:

#ifndef __OPENCV_CORE_EIGEN_HPP__
#define __OPENCV_CORE_EIGEN_HPP__

#ifdef __cplusplus

#include "opencv/cxcore.h"
#include <eigen3/Eigen/Dense>

namespace cv
{

template<typename _Tp, int _rows, int _cols, int _options, int _maxRows, int _maxCols>
void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, Mat& dst )
{
    if( !(src.Flags & Eigen::RowMajorBit) )
    {
        Mat _src(src.cols(), src.rows(), DataType<_Tp>::type,
              (void*)src.data(), src.stride()*sizeof(_Tp));
        transpose(_src, dst);
    }
    else
    {
        Mat _src(src.rows(), src.cols(), DataType<_Tp>::type,
                 (void*)src.data(), src.stride()*sizeof(_Tp));
        _src.copyTo(dst);
    }
}

template<typename _Tp, int _rows, int _cols, int _options, int _maxRows, int _maxCols>
void cv2eigen( const Mat& src,
               Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& dst )
{
    CV_DbgAssert(src.rows == _rows && src.cols == _cols);
    if( !(dst.Flags & Eigen::RowMajorBit) )
    {
        Mat _dst(src.cols, src.rows, DataType<_Tp>::type,
                 dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
        if( src.type() == _dst.type() )
            transpose(src, _dst);
        else if( src.cols == src.rows )
        {
            src.convertTo(_dst, _dst.type());
            transpose(_dst, _dst);
        }
        else
            Mat(src.t()).convertTo(_dst, _dst.type());
        CV_DbgAssert(_dst.data == (uchar*)dst.data());
    }
    else
    {
        Mat _dst(src.rows, src.cols, DataType<_Tp>::type,
                 dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
        src.convertTo(_dst, _dst.type());
        CV_DbgAssert(_dst.data == (uchar*)dst.data());
    }
}

template<typename _Tp>
void cv2eigen( const Mat& src,
               Eigen::Matrix<_Tp, Eigen::Dynamic, Eigen::Dynamic>& dst )
{
    dst.resize(src.rows, src.cols);
    if( !(dst.Flags & Eigen::RowMajorBit) )
    {
        Mat _dst(src.cols, src.rows, DataType<_Tp>::type,
             dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
        if( src.type() == _dst.type() )
            transpose(src, _dst);
        else if( src.cols == src.rows )
        {
            src.convertTo(_dst, _dst.type());
            transpose(_dst, _dst);
        }
        else
            Mat(src.t()).convertTo(_dst, _dst.type());
        CV_DbgAssert(_dst.data == (uchar*)dst.data());
    }
    else
    {
        Mat _dst(src.rows, src.cols, DataType<_Tp>::type,
                 dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
        src.convertTo(_dst, _dst.type());
        CV_DbgAssert(_dst.data == (uchar*)dst.data());
    }
}


template<typename _Tp>
void cv2eigen( const Mat& src,
               Eigen::Matrix<_Tp, Eigen::Dynamic, 1>& dst )
{
    CV_Assert(src.cols == 1);
    dst.resize(src.rows);

    if( !(dst.Flags & Eigen::RowMajorBit) )
    {
        Mat _dst(src.cols, src.rows, DataType<_Tp>::type,
                 dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
        if( src.type() == _dst.type() )
            transpose(src, _dst);
        else
            Mat(src.t()).convertTo(_dst, _dst.type());
        CV_DbgAssert(_dst.data == (uchar*)dst.data());
    }
    else
    {
        Mat _dst(src.rows, src.cols, DataType<_Tp>::type,
                 dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
        src.convertTo(_dst, _dst.type());
        CV_DbgAssert(_dst.data == (uchar*)dst.data());
    }
}


template<typename _Tp>
void cv2eigen( const Mat& src,
               Eigen::Matrix<_Tp, 1, Eigen::Dynamic>& dst )
{
    CV_Assert(src.rows == 1);
    dst.resize(src.cols);
    if( !(dst.Flags & Eigen::RowMajorBit) )
    {
        Mat _dst(src.cols, src.rows, DataType<_Tp>::type,
                 dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
        if( src.type() == _dst.type() )
            transpose(src, _dst);
        else
            Mat(src.t()).convertTo(_dst, _dst.type());
        CV_DbgAssert(_dst.data == (uchar*)dst.data());
    }
    else
    {
        Mat _dst(src.rows, src.cols, DataType<_Tp>::type,
                 dst.data(), (size_t)(dst.stride()*sizeof(_Tp)));
        src.convertTo(_dst, _dst.type());
        CV_DbgAssert(_dst.data == (uchar*)dst.data());
    }
}

}

#endif

#endif

希望这对你有所帮助!

这篇关于如何使用OpenCV执行LU分解?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆