我可以回答如何在VC10和g ++上完成此操作,但我仍有一些问题需要解决。我是写模板函数的新手。通常需要在cv :: Mat
和arma :: mat
矩阵对象之间进行转换,因为Armadillo具有更完整的线性代数功能。OpenCV将其矩阵存储在行主序中,而Armadillo将其矩阵存储在列主序中,这是问题的一个组成部分。我已创建了以下模板函数,在VC10和g ++ 4.9上进行了测试,可用于float
和double
类型的矩阵:
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());
#if defined(WIN32)
arma_mat_out = arma::Mat<T>(temp.ptr<T>(),
static_cast<arma::uword>(temp.cols),
static_cast<arma::uword>(temp.rows),
true,
true);
#elif defined(LINUX)
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
};
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;
}
我的进一步问题是:
你有什么想法,我做错了什么?这似乎是VC10比g++更宽容的情况,但如果我想继续使用第一个(更好的)版本与g ++,我漏掉了什么?
在 Cv_mat_to_arma_mat(...)
中,有没有建议可以解决行主序与行序问题而不创建临时变量?cv_mat_in.t()
不会改变 cv_mat_in
的内部存储指针,它只是一个 cv::MatExpr
。
欢迎对这些函数的风格、安全性或性能提出任何批评。当然,它们不适用于具有多个通道的 cv::Mat
。