我正在尝试在 2772x128 矩阵和 4000x128 矩阵之间制作一个乘积。两者都是 SIFT 描述符矩阵,使用以下代码:
Mat a = Mat(nframes, descrSize, CV_8U, DATAdescr);
Mat b = Mat(vocabulary_size, descrSize, CV_8U, vocabulary);
Mat ab =a * b.t();
问题是在计算乘积时,它会抛出错误
err_msg = 0x00cdd5e0 "..\..\..\src\opencv\modules\core\src\matmul.cpp:711: error: (-215) type == B.type() && (type == CV_32FC1 || type == CV_64FC1 || type == CV_32FC2 || type == CV_64FC2)"
解决此问题的方法是将数据类型转换为 CV_32FC1
Mat a = Mat(nframes, descrSize, CV_8U, DATAdescr);
Mat b = Mat(vocabulary_size, descrSize, CV_8U, vocabulary);
a.convertTo(a, CV_32FC1);
b.convertTo(b, CV_32FC1);
Mat ab = a * b.t();
效果很好,但是耗时太多,大约1.2秒。我想尝试相同的产品但使用整数,看看是否可以加快速度。难道我做错了什么?我看不出有什么理由不能在 CV_8U 矩阵之间进行矩阵乘积。
编辑:答案与使用其他库或解决其他方法有关。我正在考虑打开一个新线程并提出解决我的问题的建议,但是有人可以回答我最初的疑问吗?我不能将 CV_8U 或 CV32S 矩阵相乘吗?真的吗?
最佳答案
在您的 other message 中你说下面的代码需要0.9秒。
MatrixXd A = MatrixXd::Random(1000, 1000);
MatrixXd B = MatrixXd::Random(1000, 500);
MatrixXd X;
我在我的机器上尝试了一些基准测试,在 Linux 上运行的 intel core i7。我的完整基准代码如下:
#include <Eigen/Dense>
using namespace Eigen;
int
main(int argc, char *argv[])
{
MatrixXd A = MatrixXd::Random(2772, 128);
MatrixXd B = MatrixXd::Random(4000, 128);
MatrixXd X = A*B.transpose();
}
我只是使用 Linux 中的 time 命令,因此运行时间包括可执行文件的启动和停止。
1/不进行优化编译(gcc 编译器):
g++ -I/usr/include/eigen3 matcal.cpp -O0 -o matcal
time ./matcal
real 0m13.177s -> this is the time you should be looking at
user 0m13.133s
sys 0m0.022s
13秒,太慢了。顺便说一句,如果没有矩阵乘法,则需要 0.048 秒,而矩阵更大则需要 0.9 秒的示例。为什么??
使用 Eigen 进行编译器优化非常重要。 2/进行一些优化编译:
g++ -I/usr/include/eigen3 matcal.cpp -O2 -o matcal
time ./matcal
real 0m0.324s
user 0m0.298s
sys 0m0.024s
现在 0.324s,更好了!
3/切换所有优化标志(至少是我所知道的所有优化标志,我不是该领域的专家)
g++ -I/usr/include/eigen3 matcal.cpp -O3 -march=corei7 -mtune=corei7 -o matcal
time ./matcal
real 0m0.317s
user 0m0.291s
sys 0m0.024s
0.317,接近,但增加了几毫秒(在一些测试中始终如此)。因此,在我看来,您对 Eigen 的使用确实存在问题,要么您没有切换编译器优化,要么您的编译器没有自行执行此操作。
我不是 Eigen 专家,我只使用过它几次,但我认为文档非常好,您可能应该阅读它以充分利用它。
关于与 MatLab 的性能比较,上次我读到 Eigen 时它不是多线程的,而 MatLab 可能使用多线程库。对于矩阵乘法,您可以将矩阵分成几个 block ,并使用 TBB 并行化每个 block 的乘法
关于c++ - cv::mat CV_8U 产品错误和缓慢的 CV_32F 产品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12479663/