将CV :: Mat转换为Arma :: mat

时间:2014-09-30 10:47:42

标签: c++ opencv armadillo

我尝试将Opencv中的表单矩阵转换为armadillo中的矩阵

我在this link

中找到了这个功能

但是当我试着给它打电话时给我错误:

  1. 错误C2783:' arma :: Mat cvMat2armaMat(cv :: Mat&)' :无法推断出' T3'
  2. 的模板参数
  3. 智能感知:没有功能模板的实例" cvMat2armaMat"匹配参数列表
  4. 这是功能:

    template<class T3>
     arma::Mat <T3> cvMat2armaMat(cv::Mat & cvMatIn) 
    { 
        return armaConv (cvMatIn.data, cvMatIn.rows, cvMatIn.cols,false); 
    
    }
    

    这是函数调用(当我调用func时出现错误)

    cv::Mat CurrentImage    = imread(path, 0);
    
    arma::mat singleImage = cvMat2armaMat (CurrentImage);
    

    我该怎么办?

2 个答案:

答案 0 :(得分:1)

您需要指定arma::mat<XXX>返回的cvMat2armaMat()类型 什么是armaConv
也许你是这个意思:

template<class T3>
arma::Mat <T3> cvMat2armaMat(cv::Mat & cvMatIn) 
{ 
    return arma::Mat <T3> (cvMatIn.data, cvMatIn.rows, cvMatIn.cols,false); 
}

并且呼叫是这样的:

auto singleImage = cvMat2armaMat<float>(CurrentImage);

或者您需要switch类型cv::Mat

答案 1 :(得分:1)

我可以回答如何在VC10和g ++上执行此操作但我还有一些问题需要解决。我是编写模板化函数的新手。由于犰狳具有更完整的线性代数功能,因此通常需要在cv::Matarma::mat矩阵对象之间进行转换。 OpenCV以行主顺序存储它的矩阵,而Armadillo以列主要顺序存储它的矩阵,这是该问题的一个组成部分。我创建了以下模板化函数,这些函数已经在VC10和g ++ 4.9中测试过,可用于floatdouble类型矩阵:

template<typename T>
static void Cv_mat_to_arma_mat(const cv::Mat_<T>& cv_mat_in, arma::Mat<T>& arma_mat_out)
{
    cv::Mat_<T> temp(cv_mat_in.t()); //todo any way to not create a temporary?
#if defined(WIN32)
    //This compiles on VC10 but not g++ 4.9 (on Debian with OpenCV 2.4.9.1 and Arma 4.320.0)
    arma_mat_out = arma::Mat<T>(temp.ptr<T>(), //<<"error: expected primary-expression before '(' token"
                                static_cast<arma::uword>(temp.cols),
                                static_cast<arma::uword>(temp.rows),
                                true,
                                true);
#elif defined(LINUX)
    //This compiles on both but is not as nice
    arma_mat_out = arma::Mat<T>(reinterpret_cast<T*>(temp.data),
                                static_cast<arma::uword>(temp.cols),
                                static_cast<arma::uword>(temp.rows),
                                true,
                                true);
#endif
};

//This one is fine on both 
template<typename T>
static void Arma_mat_to_cv_mat(const arma::Mat<T>& arma_mat_in,cv::Mat_<T>& cv_mat_out)
{
    cv::transpose(cv::Mat_<T>(static_cast<int>(arma_mat_in.n_cols),
                              static_cast<int>(arma_mat_in.n_rows),
                              const_cast<T*>(arma_mat_in.memptr())),
                  cv_mat_out);
};

此代码可以使用以下命令运行:

std::cout << "Testing arma::mat<->cv::Mat  <double>:" << std::endl;
{
    arma::Mat<double> A(3,2);
    A << 1 << 2 << arma::endr
      << 3 << 4 << arma::endr
      << 5 << 6 << arma::endr;
    cv::Mat_<double> cv_A(3,2);
    M_math::Arma_mat_to_cv_mat<double>(A, cv_A);
    std::cout << "Arma_mat_to_cv_mat<double>" << std::endl;
    std::cout << A << std::endl;
    std::cout << cv_A << std::endl;
    std::cout << "Cv_mat_to_arma_mat<double>" << std::endl;
    M_math::Cv_mat_to_arma_mat<double>(cv_A, A);
    std::cout << cv_A << std::endl;
    std::cout << A << std::endl;
}
std::cout << "Now <float>" << std::endl;
{
    arma::Mat<float> A(3,2);
    A << 1 << 2 << arma::endr
      << 3 << 4 << arma::endr
      << 5 << 6 << arma::endr;
    cv::Mat_<float> cv_A(3,2);
    M_math::Arma_mat_to_cv_mat<float>(A, cv_A);
    std::cout << "Arma_mat_to_cv_mat<float>" << std::endl;
    std::cout << A << std::endl;
    std::cout << cv_A << std::endl;
    std::cout << "Cv_mat_to_arma_mat<float>" << std::endl;
    M_math::Cv_mat_to_arma_mat<float>(cv_A, A);
    std::cout << cv_A << std::endl;
    std::cout << A << std::endl;
}

我的进一步问题是:

  1. 知道我做错了什么吗?这似乎是VC10比g ++更宽松的情况,但如果我想继续使用第一个(更好的)版本和g ++,我会错过什么?

  2. Cv_mat_to_arma_mat(...)中是否有任何建议可以绕过行主要订单与行顺序问题而不创建临时? cv_mat_in.t()不会改变cv_mat_in中的内部内存指针,它只是cv::MatExpr

  3. 对这些功能的风格,安全性或性能的任何批评都将受到赞赏。当然,它们不适用于具有多个频道的cv::Mat