计算OpenCv中cv :: Mat的外(张量)乘积

时间:2015-04-22 21:09:47

标签: c++ opencv

有没有办法使用{{计算某些列向量 z 的外部产品( z *转置( z )) 1}} OpenCV中的数据结构?

我检查了the documentation并且没有内置功能。但我试图将标准矩阵乘法表达式(*)与fatal: No names found, cannot describe anything.类型的向量一起使用时遇到异常。

这是(伪)代码:

cv::Mat

外部产品计算提供例外。 (是的,我的实际代码中的tmp矩阵中有实际值,但此描述提供了有关所用数据类型的更多信息)

理想情况下,cv::Mat应最终为9x9矩阵。

我可以使用cv::Mat tmp = cv::Mat::zeros(9, 1, CV_32SC1) cv::Mat outerProduct = tmp * tmp.t(); 的缩放倍增属性(即按列尺寸重复列向量cv::Mat outerProduct),对于每列,按索引中的值缩放元素 - { {3}}):

cv::Mat

...但如果有更好的方法会很好。

2 个答案:

答案 0 :(得分:8)

请注意,虽然我的回答是正确的,但@kaanoner's answer会提供更好的效果。

他们将这些方法隐藏在你最不期望的地方。这个位于Operations on Arrays,名为mulTransposed

cv::Mat tmp = (Mat_<double>(9,1) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cv::Mat outerProduct;
mulTransposed(tmp, outerProduct, false);

第三个参数是aTa。如果是,则该方法计算 T a。如果它是假的,它会计算a T

输出是:

tmp = 
[1; 2; 3; 4; 5; 6; 7; 8; 9]
outerProduct = 
[1, 2, 3, 4, 5, 6, 7, 8, 9;
 2, 4, 6, 8, 10, 12, 14, 16, 18;
 3, 6, 9, 12, 15, 18, 21, 24, 27;
 4, 8, 12, 16, 20, 24, 28, 32, 36;
 5, 10, 15, 20, 25, 30, 35, 40, 45;
 6, 12, 18, 24, 30, 36, 42, 48, 54;
 7, 14, 21, 28, 35, 42, 49, 56, 63;
 8, 16, 24, 32, 40, 48, 56, 64, 72;
 9, 18, 27, 36, 45, 54, 63, 72, 81]

查看源代码,CV_32S似乎不支持mulTransposed。以下是它们指定的源和目标类型:

(stype == CV_8U && dtype == CV_32F)
(stype == CV_8U && dtype == CV_64F)
(stype == CV_16U && dtype == CV_32F)
(stype == CV_16U && dtype == CV_64F)
(stype == CV_16S && dtype == CV_32F)
(stype == CV_16S && dtype == CV_64F)
(stype == CV_32F && dtype == CV_32F)
(stype == CV_32F && dtype == CV_64F)
(stype == CV_64F && dtype == CV_64F)

这意味着,目标类型始终是浮点类型。即使我指定了CV_16S的dtype,我也会得到一个CV_32F的矩阵。

答案 1 :(得分:3)

在我的运行中,transpose和multiply方法的速度是单mulTransposed函数调用的两倍。

Mat descriptor; //(1 rows x 192 cols, CV_32F)
Mat outerProduct;

// calculates outer products for 10000 different descriptors in a loop
mulTransposed(descriptor, outerProduct, true); // => takes 33 secs
outerProduct = descriptor.t()*descriptor; // => takes 14 secs