c++ opencv eigen

c++ - ¿Cómo utiliza OpenCV Eigen?



(2)

Al compilar OpenCV desde el origen, existe la opción CMake WITH_EIGEN, que dice "Incluir soporte Eigen3". Sin embargo, en ninguna parte de la documentación (o con Google, para el caso) puedo averiguar qué hace exactamente esto y cómo usarlo. Puedo imaginar algunas opciones:

¿Puedo seguir usando cv :: Mat, y ciertas funciones (¿cuáles?) Como cv :: Mat :: inv () comenzarán a usar los algoritmos de Eigen.

¿O la bandera WITH_EIGEN básicamente no hace nada y necesito convertir los cv :: Mat''s a Eigen (o usar Eigen :: Map) y luego usar los algoritmos de Eigen manualmente?


Aquí está mi ejemplo de interoperabilidad Eigen + OpenCV, espero que sea útil:

// #define EIGEN_RUNTIME_NO_MALLOC // Define this symbol to enable runtime tests for allocations #include <Eigen/Dense> #include <Eigen/Sparse> #include <vector> #include <Eigen/IterativeLinearSolvers> #include <iostream> #include "opencv2/core/eigen.hpp" #include "opencv2/opencv.hpp" using namespace Eigen; using namespace cv; using namespace std; void EnergyFilter(Mat& src,Mat& dst,double alpha) { int n_pixels=src.rows*src.cols; // Image to row-vector Mat m=src.reshape(1,n_pixels).clone(); // To double m.convertTo(m,CV_64FC1); // Eigen vectors VectorXd I(n_pixels); VectorXd u(n_pixels); // convert image from openCV to Eigen cv2eigen(m,I); // SparseMatrix<double> A(n_pixels,n_pixels); // Fill sparse martix using triplets typedef Eigen::Triplet<double> T; std::vector<T> tripletList; // Filter parameter (smoothing factor) //double alpha=-0.1; // Set values for(int i=0;i<n_pixels;i++) { tripletList.push_back(T(i,i,1+4*alpha)); if((i+1) < n_pixels){tripletList.push_back(T(i,i+1,-alpha));} // +1 if((i-1) >= 0){tripletList.push_back(T(i,i-1,-alpha));} // -1 if((i+src.cols) < n_pixels){tripletList.push_back(T(i,i+src.cols,-alpha));} // +3 if((i-src.cols) >= 0){tripletList.push_back(T(i,i-src.cols,-alpha));} // -3 } // Boundary values of main diag tripletList.push_back(T(0,0,1+2*alpha)); for(int i=1;i<src.cols;i++) { tripletList.push_back(T(i,i,1+3*alpha)); } // tripletList.push_back(T(n_pixels-1,n_pixels-1,1+2*alpha)); for(int i=1;i<src.cols;i++) { tripletList.push_back(T(i,n_pixels-i-1,1+3*alpha)); } // Init sparse matrix A.setFromTriplets(tripletList.begin(),tripletList.end()); tripletList.clear(); // Solver init ConjugateGradient<SparseMatrix<double> > cg; cg.compute(A); // Solve linear systyem u = cg.solve(I); std::cout << "#iterations: " << cg.iterations() << std::endl; std::cout << "estimated error: " << cg.error() << std::endl; // Get the solution dst=Mat(n_pixels,1,CV_64FC1); eigen2cv(u,dst); dst=dst.reshape(1,src.rows); dst.convertTo(dst,CV_8UC1); } int main(int argc, char* argv[]) { namedWindow("image"); namedWindow("result"); Mat img=imread("d://ImagesForTest//lena.jpg",1); imshow("image",img); waitKey(10); Mat res; vector<Mat> ch; cv::split(img,ch); for(int i=0;i<3;i++) { EnergyFilter(ch[i],res,3); res.copyTo(ch[i]); } cv::merge(ch,res); // show the resilt imshow("result",res); waitKey(0); return 0; }


Después de trabajar con él por un tiempo, puedo dar la respuesta:

El indicador WITH_EIGEN no hace nada excepto que las funciones de interoperabilidad de eigen-opencv estén disponibles.

¿Puedo seguir usando cv :: Mat, y ciertas funciones (¿cuáles?) Como cv :: Mat :: inv () comenzarán a usar los algoritmos de Eigen.

No, cv :: Mat :: inv () no tiene lógica inteligente y usará los algoritmos de OpenCV.

¿O la bandera WITH_EIGEN básicamente no hace nada y necesito convertir los cv :: Mat''s a Eigen (o usar Eigen :: Map) y luego usar los algoritmos de Eigen manualmente?

Exactamente, ese es el camino a seguir. Sin embargo, no recomendaría necesariamente usar cv2eigen () y eigen2cv (). Usé Eigen :: Map para solo mapear la memoria (sin costo al copiar nada) y cv :: Mat (void *, ...) para mapear los datos. Sin embargo, tenga cuidado con las banderas de fila / col mayor y esas cosas.