2014-02-06 70 views
10

從源代碼編譯OpenCV時,有CMake選項WITH_EIGEN,它說「包含Eigen3支持」。然而,無論在文檔(或谷歌,就此而言),我可以找出究竟是什麼以及如何使用它。我可以想象幾個選項:OpenCV如何利用特徵?

我可以繼續使用cv :: Mat,並且像cv :: Mat :: inv()這樣的某些函數(哪一個?)將開始使用Eigen的算法?

或者WITH_EIGEN標誌基本上什麼都不做,我需要將cv :: Mat's轉換爲Eigen(或使用Eigen :: Map),然後手動使用Eigen的算法?

回答

13

使用它了一會兒後,我可以提供答案:

的WITH_EIGEN標誌什麼都不做除了使本徵opencv互操作性功能可用。

我可以繼續使用cv :: Mat,並且像cv :: Mat :: inv()這樣的某些函數(哪一個?)將開始使用Eigen的算法?

不,cv :: Mat :: inv()沒有智能邏輯,將使用OpenCV算法。

或者WITH_EIGEN標誌基本上什麼都不做,我需要將cv :: Mat's轉換爲Eigen(或使用Eigen :: Map),然後手動使用Eigen的算法?

確切的說,這就是要走的路。 雖然我不一定推薦使用cv2eigen()和eigen2cv()。我使用Eigen :: Map來映射內存(無需複製任何內容)和cv :: Mat(void *,...)來映射數據。使用行/列主標誌和東西時要小心。

+0

對於Eigen和cv :: Mat之間的正確映射,無需複製數據,請在此處查看我的答案:http://stackoverflow.com/questions/14783329/opencv-cvmat-and-eigenmatrix/21706778#21706778 – Ela782

3

這裏是我的艾根+ OpenCV的互操作性例子,希望能對大家有用:

// 
#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; 
} 
+1

是的,這很有用,謝謝你的例子。但是,我意識到這種類型的例子,它不回答我的問題:OCV如何利用特徵。我想答案是:它不是!用WITH_EIGEN編譯就意味着你可以訪問互操作函數和Eigen頭文件。除非有人比我知道的更多。 – Ela782