簡體   English   中英

如何將'cv :: Mat'轉換為'double'?

[英]How do I convert 'cv::Mat' to 'double'?

我正在嘗試使用C ++和OpenCV 3.0.0(beta)在eclispe中從math.stackexchange實現此答案
我正在使用下面的代碼。

Mat a = (Mat_<double>(1,3) <<   rotationMatrix1.at<double>(2,0), rotationMatrix1.at<double>(2,1), rotationMatrix1.at<double>(2,2));
Mat b = (Mat_<double>(1,3) <<   rotationMatrix2.at<double>(2,0), rotationMatrix2.at<double>(2,1), rotationMatrix2.at<double>(2,2));

Mat f = (Mat_<double>(1,3) << a , (b-(a.dot(b))*a)/norm(b-(a.dot(b))*a),a.cross(b));
Mat f1 = f.inv(DECOMP_CHOLESKY);

Mat g = (Mat_<double>(3,3) << a.dot(b), - norm(a.cross(b)), 0,  norm(a.cross(b)), a.dot(b), 0,  0,0,1);

Mat u = f1.inv(DECOMP_CHOLESKY) * g * f1;

當我編譯時導致以下錯誤:

/include/opencv2/core/mat.inl.hpp:2827:15:錯誤:從類型'cv :: MatExpr'轉換為類型'double'的無效
/include/opencv2/core/mat.inl.hpp:2827:15:錯誤:類型'cv :: Mat'強制類型轉換為'double'無效

所以問題可能出在這行:

Mat f = (Mat_<double>(1,3) << a , (b-(a.dot(b))*a)/norm(b-(a.dot(b))*a),a.cross(b));

因為“ a”和“(b-(a.dot(b))* a)/ norm(b-(a.dot(b))* a)”不是“ double”。
所以我的問題是如何將它們正確地轉換為“ double”?

“轉換”它們是錯誤的事情。 您的表達有誤。 OpenCV的功能之一需要加倍,然后傳遞矩陣。 現在一行包含大約十二個函數調用(包括所有的運算符),因此在這里很難挑出一個錯誤。

只需為不同的子表達式寫出臨時變量的定義即可。 您可能會發現這些子表達式之一(您認為計算結果為雙精度)實際上計算為矩陣。 這種說法是錯誤的。 不要“修復”它以使錯誤消失。 對其進行修復,以使結果變得有意義。

例如,您可能已經忘記了將矩陣的行列式放在某處,並且我們沒有想法-我們不是領域專家。 C ++編譯器也不是。 它對行列式一無所知,只檢測類型不匹配。 顯然,采用矩陣的行列式不是“轉換”

為了提高可讀性,讓我們重寫行

Mat f = (Mat_<double>(1,3) << a , (b-(a.dot(b))*a)/norm(b-(a.dot(b))*a),a.cross(b));    

對此:

cv::Mat t0 = b - a.dot( b ) * a; // size: 1x3
cv::Mat t1 = t0 / norm(t0);      // size: 1x3
cv::Mat t2 = a.cross(b);         // size: 1x3
Mat f = (Mat_<double>(1,3) << a , t1 , t2);
//                            ^   ^^   ^^ these are 1x3 matrices (== 9 double value),
//                                        but matrix f expects 3 doubles.

查看您引用的數學堆棧問題 ,該函數

FFi = @(A,B) [ A (B-dot(A,B)*A)/norm(B-dot(A,B)*A) cross(B,A) ];

返回一個3×3矩陣,因此在任何情況下Mat_<double>(1,3)是錯誤的。

要解決此問題,請創建一個3×3矩陣,然后將上述臨時變量的值分配給該矩陣的列:

cv::Mat1d f(3,3);
f( cv::Rect( 0, 0, 1, 3 ) ) = a.t(); // transposed, cf. note below
f( cv::Rect( 0, 0, 2, 3 ) ) = t1.t(); // transposed, cf. note below
f( cv::Rect( 0, 0, 3, 3 ) ) = t2.t(); // transposed, cf. note below

注意:請注意您的向量是1×3,而不是參考問題中的3×1。 如果幸運的話,這會觸發運行時錯誤。 如果不是,則代碼會編譯並運行,但結果是錯誤的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM