Skip to content

Instantly share code, notes, and snippets.

@psycharo-zz
Last active May 4, 2020 10:54
Show Gist options
  • Save psycharo-zz/5b724fbae5f07008e7de to your computer and use it in GitHub Desktop.
Save psycharo-zz/5b724fbae5f07008e7de to your computer and use it in GitHub Desktop.
convertions between armadillo and opencv
// convert an OpenCV multi-channel matrix to Armadillo cube. A copy is made
template <typename T, int NC>
Cube<T> to_arma(const cv::Mat_<cv::Vec<T, NC>> &src)
{
vector<cv::Mat_<T>> channels;
Cube<T> dst(src.cols, src.rows, NC);
for (int c = 0; c < NC; ++c)
channels.push_back({src.rows, src.cols, dst.slice(c).memptr()});
cv::split(src, channels);
return dst;
}
// convert an OpenCV matrix to Armadillo matrix. NOTE: a copy is made
template <typename T>
Mat<T> to_arma(const cv::Mat_<T> &src)
{
Mat<T> dst(src.cols, src.rows);
src.copyTo({src.rows, src.cols, dst.memptr()});
return dst;
}
// convert an Armadillo cube to OpenCV matrix. NOTE: a copy is made
template <typename T>
cv::Mat to_cvmat(const Cube<T> &src)
{
vector<cv::Mat_<T>> channels;
for (size_t c = 0; c < src.n_slices; ++c)
{
auto *data = const_cast<T*>(src.slice(c).memptr());
channels.push_back({int(src.n_cols), int(src.n_rows), data});
}
cv::Mat dst;
cv::merge(channels, dst);
return dst;
}
// convert an Armadillo matrix to OpenCV matrix. NOTE: no copy is made
template <typename T>
cv::Mat_<T> to_cvmat(const Mat<T> &src)
{
return cv::Mat_<double>{int(src.n_cols), int(src.n_rows), const_cast<T*>(src.memptr())};
}
@willard-yuan
Copy link

Hi psycharo,
Recently I faced a probem: I want to transform the opencv mat to arma mat. I found a solution in stackoverflow Conversion between cv::Mat and arma::mat. But I failed to solve it following the solution. The code of mine is as follows:

cv::Mat imgGray = cv::imread("test.jpg", CV_LOAD_IMAGE_GRAYSCALE);
cout << "rows: " << imgGray.rows << '\t' << "cols: " << imgGray.cols << endl;
cv::Mat imgGrayT = imgGray.t();
cout << "rows: " << imgGrayT.rows << '\t' << "cols: " << imgGrayT.cols << endl;
arma::mat arma_mat(reinterpret_cast<double*>(imgGrayT.data), imgGrayT.rows, imgGrayT.cols);

when it runs at arma::mat arma_mat(reinterpret_cast<double*>(imgGrayT.data), imgGrayT.rows, imgGrayT.cols), it throws an error. I don't know how to fixed the problem. Then I find your code here. But I'm familiar with the template. Would you like to give some examples to illustrate how to call the functions of your code?

@taiwuchiang
Copy link

The problem with the above code is the imgGray is not using double. So when you cast it to double, it runs out of data.
You could use:
arma::Mat and don't need to cast it
arma::Mat arma_mat(opencv_mat.data, opencv_mat.cols, opencv_mat.rows);

@sarimmehdi
Copy link

Hello, can you show us how to use this? I am unable to use this to convert opencv mat to arma cube.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment