2013-08-30 175 views
9

我正在處理一些代碼,其中做了很多3x3矩陣乘法以及使用旋轉矩陣等的3d點的一些轉換。我決定使用OpenCV核心功能進行數學運算。使用添加到cv::Mat類中的近期構造函數將cv::Point3d直接轉換爲3x1 cv::Mat的可能性大大減少並簡化了代碼。將3x1或1x3 cv :: Mat轉換爲cv :: Point3d?

我現在想知道的是,如果有一種簡單的方法將3x1或1x3 cv::Mat轉換爲cv::Point3d?我總是可以這樣做:

cv::Mat mat(3,1,CV_64FC1); 
cv::Point3d p (mat.at<double>(0,0), mat.at<double>(1,0), mat.at<double>(2,0)); 

cv::Mat mat(3,1,CV_64FC1); 
const double *data = mat.ptr<double>(0); 
cv::Point3d p (data[0], data[1], data[2]); 

我對性能(避免3調用at方法)非常擔心。

回答

10

cv::Point3d有一個構造函數,它允許從cv::Mat直接創造:

cv::Mat mat(3,1,CV_64FC1); 
cv::Point3d p(mat); 

使用cv::Matx而不是cv::Mat你的數學運算,你可能沒有考慮另一種可能性。我覺得它更容易使用,並提供更多的功能,如Point型的乘法,而無需轉換:

cv::Point3d p(1,2,3); 
cv::Matx33d m = cv::Matx33d::eye(); 
cv::Point3d p2 = m * p; 

cv::Matx也靜態分配的,而不是動態(如cv::Mat),如果你真的需要額外的一點表現。但是,正如所有與性能相關的建議一樣:確保您正在優化的內容實際上是分析的瓶頸。

+0

太棒了!我一直在尋找在OpenCV的core.hpp標頭爲Point_類像一個構造函數: 'Point_(常量墊& sz);' 因爲我沒有發現它,我認爲沒有辦法做到這一點。此外我沒有「T注意到的 'Point_(const的存在VEC <_Tp, 2> & v);' MATX的使用似乎是我的目的非常有用的。非常感謝! – piponazo

+1

準確的說,沒有構造函數'Point_ '/ 'Point3_ ''需要一個'cv :: Mat',而不是一個隱式的[cast operator](https://github.com/Itseez/opencv/blob/2.4/modules/core/include/opencv2/core/ core.hpp#L1856)放入'cv :: Mat'中,將其轉換爲其他f像'Vec'或'Matx'這樣的ixed大小的類('Vec'被Point構造函數接受) – Amro

+0

我想知道爲什麼我們可以用'matrix'來轉換'cv :: Point',但不能'cv :: Vec'。在後一種情況下,我們需要首先將'cv :: Vec'轉換爲'cv :: Point'。 –