Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在OpenCv中计算cv::Mat的外积(张量)_C++_Opencv - Fatal编程技术网

C++ 在OpenCv中计算cv::Mat的外积(张量)

C++ 在OpenCv中计算cv::Mat的外积(张量),c++,opencv,C++,Opencv,是否有一种方法可以使用OpenCV中的cv::Mat数据结构计算某些列向量的外积(z*转置(z) 我检查过了,没有内置的功能。但我在尝试将标准矩阵乘法表达式(*)与类型为cv::Mat的向量一起使用时遇到了异常 以下是(伪)代码: 外积计算给出了例外情况。(是的,我在实际代码的tmp矩阵中有实际值,但本说明提供了有关所用数据类型的更多信息) 理想情况下,cv::Mat outerProduct应该以9x9矩阵结束 我可以使用cv::Mat的缩放倍增属性(即,按维度重复列向量tmp,并针对每列,按

是否有一种方法可以使用OpenCV中的
cv::Mat
数据结构计算某些列向量的外积(z*转置(z

我检查过了,没有内置的功能。但我在尝试将标准矩阵乘法表达式(*)与类型为
cv::Mat
的向量一起使用时遇到了异常

以下是(伪)代码:

外积计算给出了例外情况。(是的,我在实际代码的tmp矩阵中有实际值,但本说明提供了有关所用数据类型的更多信息)

理想情况下,
cv::Mat outerProduct
应该以9x9矩阵结束

我可以使用
cv::Mat
的缩放倍增属性(即,按维度重复列向量
tmp
,并针对每列,按索引中的值缩放元素):

cv::Mat outerProduct=cv::repeat(tmp,1,9);
对于(int i=0;i<9;i++)
{
外层产品列(i)*=tmp.at(i,0);
}

…但如果有更好的方法,那就太好了。

请注意,虽然我的答案是正确的,但性能会更好


他们把这些方法偷偷带到你最意想不到的地方。这个在里面,叫做

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

(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
,我得到的矩阵是
CV_32F

在我的运行中,转置和乘法方法的速度是单个函数调用的两倍

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 

也许我做错了什么,但是当我在
CV\u 32SC1
类型的
Mat
上调用该函数时,我从OpenCV得到了一个“不支持的格式或格式组合”错误。我检查了文档,他们特别提到mulTransposed“不仅可以乘法浮点矩阵。”对我来说
tmp
是type
CV\u 32SC1
,但当我指定
外部产品的类型时,它仍然失败。有什么想法吗?正在检查,但当我使用
CV_32SC1
而不是
double
时,我看到了同样的情况,即使我将
dtype
参数指定为
CV_32SC1
-1
。奇怪。。。我得四处看看。再次感谢!哇!如果只是想踢一脚,可以试试
CV\u 16SC1
。我正在查看代码,没有提到
CV_32S
,只有16位整数。不支持int类型,您需要CV_32F或类似的:mulTransposed“不仅可以乘法浮点矩阵”。请参阅下面@biker的答案。他列出了支持的类型。整数是8位和16位的类型。这真的很有趣。我注意到的一点是,输入数组必须是浮点数,但这似乎并不是这样一个性能增益的很大限制。抢手货
cv::Mat tmp = (Mat_<double>(9,1) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cv::Mat outerProduct;
mulTransposed(tmp, outerProduct, false);
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]
(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)
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