36

cv::MatOpenCVオブジェクトをに変換する可逆的な方法はありEigen::Matrixますか?

例:何らかの方法:

cv::Mat cvMat;
Eigen::Matrix eigMat;
camera->retrieve(cvMat);

// magic to convert cvMat to eigMat
// work on eigMat
// convert eigMat back to cvMat

imshow("Image", cvMat);

とを使ってみましcv2eigeneigen2cvが、結果cvMatが完全に壊れてしまい、理由がよくわかりません。寸法は正しいですが、グラフィックは完全にゴミ箱に入れられているので、おそらくピクセルあたりのバイト数またはデータサイズの問題ですか?

4

5 に答える 5

73

使用することもできます

void eigen2cv(const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, Mat& dst)

void cv2eigen(const Mat& src, Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& dst)

から#include <opencv2/core/eigen.hpp>

于 2013-07-03T17:16:33.217 に答える
36

Eigen SDKで直接使用するには、Eigen::Mapを使用してOpenCVマトリックスをラップすることを検討する必要があります。これにより、Eigenに実装されているほぼすべての機能をOpenCVによって割り当てられたマトリックスに適用できます。

特に、Cv::Matバッファへのポインタを提供するEigen::Mapをインスタンス化するだけです。

//allocate memory for a 4x4 float matrix
cv::Mat cvT(4,4,CV_32FC1); 

//directly use the buffer allocated by OpenCV
Eigen::Map<Matrix4f> eigenT( cvT.data() ); 

Eigen :: Mapの詳細については、 Eigenチュートリアル:マップクラスを参照してください。

于 2013-02-14T12:03:24.373 に答える
33

EigenとOpenCVの間で(データをコピーせずに)任意の行列をマップできます。

ただし、次の2つの点に注意する必要があります。

  • Eigenのデフォルトは列メジャーストレージであり、OpenCVは行メジャーストレージを格納します。したがって、OpenCVデータをマッピングするときは、Eigen::RowMajorフラグを使用してください。

  • OpenCVマトリックスは連続的である必要があります(つまり、ocvMatrix.isContinuous()はtrueである必要があります)。これは、マトリックスの作成時に一度にマトリックスのストレージを割り当てる場合(たとえば、以下の例のように、またはマトリックスがMat W = A.inv();のような操作の結果である場合)に当てはまります。

例:

Mat A(20, 20, CV_32FC1);
cv::randn(A, 0.0f, 1.0f); // random data

// Map the OpenCV matrix with Eigen:
Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> A_Eigen(A.ptr<float>(), A.rows, A.cols);

// Do something with it in Eigen, create e.g. a new Eigen matrix:
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> B = A_Eigen.inverse();

// create an OpenCV Mat header for the Eigen data:
Mat B_OpenCV(B.rows(), B.cols(), CV_32FC1, B.data());

マルチチャネル行列(画像など)の場合、Pierluigiがコメントで提案したとおりに「Stride」を使用できます。

于 2014-02-11T16:00:16.080 に答える
4

これは私のために働きます、

  #include <opencv2/core/eigen.hpp>

  cv::Mat image;
  image = cv::imread("/dataset/images/15207_angle_image.jpg", CV_LOA D_IMAGE_GRAYSCALE);   // Read the file
  Eigen::Matrix<float,Eigen::Dynamic, Eigen::Dynamic> eigen_mat;
  cv::cv2eigen(image, eigen_mat);
于 2019-05-25T13:20:51.127 に答える
3

Pierluigiのバージョンは、3チャンネルの画像では完全には機能しませんでした。いくつかの調査の後、私は私のために働いた次の解決策で終わりました:

using namespace Eigen;

constexpr uint32_t height = 3;
constexpr uint32_t width = 7;

cv::Mat img(height, width, CV_32FC3, cv::Scalar(1.0f, 2.0f, 3.0f));

using MatrixXfRowMajor = Matrix<float, Dynamic, Dynamic, RowMajor>;
using C3Stride = Stride<Dynamic, 3>;
C3Stride c3Stride(width *3,3);


using cvMap = Map<MatrixXfRowMajor, Unaligned, C3Stride >;
cvMap imgC1(reinterpret_cast<float*>(img.data) + 0, img.rows, img.cols, c3Stride);
cvMap imgC2(reinterpret_cast<float*>(img.data) + 1, img.rows, img.cols, c3Stride);
cvMap imgC3(reinterpret_cast<float*>(img.data) + 2, img.rows, img.cols, c3Stride);

std::cout << imgC1 << std::endl << std::endl;
std::cout << imgC2 << std::endl << std::endl;
std::cout << imgC3 << std::endl << std::endl;
于 2017-07-12T12:09:04.537 に答える