有没有办法使用OpenCV中的数据结构计算外部产品(某些列向量z的z*transpose(z))?cv::Mat
我检查了文档,没有内置功能.但是我试图将标准矩阵乘法表达式(*)与类型向量一起使用时遇到异常cv::Mat.
这是(伪)代码:
cv::Mat tmp = cv::Mat::zeros(9, 1, CV_32SC1)
cv::Mat outerProduct = tmp * tmp.t();
Run Code Online (Sandbox Code Playgroud)
外部产品计算提供例外.(是的,我的实际代码中的tmp矩阵中有实际值,但此描述提供了有关所用数据类型的更多信息)
理想情况下,最终cv::Mat outerProduct应该是9x9矩阵.
我可以使用缩放倍增属性cv::Mat(即按列tmp尺寸重复列向量),对于每列,按索引中的值缩放元素 - 如同如何用手解决这种乘法一样:
cv::Mat outerProduct = cv::repeat(tmp, 1, 9);
for (int i = 0; i < 9; i++)
{
outerProduct.col(i) *= tmp.at<int>(i, 0);
}
Run Code Online (Sandbox Code Playgroud)
...但如果有一个更好的方法会很好.
请注意,虽然我的答案是正确的,但@ kaanoner的回答可以提供更好的表现.
他们将这些方法隐藏在你最不期望的地方.这个是在阵列上的操作,它被称为mulTransposed.
cv::Mat tmp = (Mat_<double>(9,1) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cv::Mat outerProduct;
mulTransposed(tmp, outerProduct, false);
Run Code Online (Sandbox Code Playgroud)
第三个参数是aTa.如果是,则该方法计算T a.如果是假的,它计算AA 牛逼.
输出是:
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]
Run Code Online (Sandbox Code Playgroud)
查看源代码,似乎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)
Run Code Online (Sandbox Code Playgroud)
这意味着,目标类型始终是浮点类型.即使我指定了dtype CV_16S,我也会得到一个矩阵CV_32F.