Opencv中gemm的使用

来源:互联网 发布:制作特效的软件 编辑:程序博客网 时间:2024/06/05 20:25

今天才发现opencv中集成了gemm啊!!之前花了很多时间在OpenBlas的上,今天在看Opencv的代码发现opencv中都已经集成了gemm函数,代码是C语言写的,2.4.9版本的文件在modules/core/src/matmul.cpp中。
函数定义如下:

void cv::gemm( InputArray matA, InputArray matB, double alpha,           InputArray matC, double beta, OutputArray _matD, int flags )

函数体相当复杂,代码行数将近600行。计算的是:
这里写图片描述

OpenCV的gemm与OpenBlas的对比

代码:

#include "opencv2/core/core.hpp"#include <opencv2/opencv.hpp>#include<iostream>#include<cblas.h>#include<windows.h>using namespace std;using namespace cv;#define LEN 30float timeOpenCV[LEN];float timeOpenBlas[LEN];int main(){    _LARGE_INTEGER time_start, time_over;    LARGE_INTEGER f;    QueryPerformanceFrequency(&f);    double dqFreq = (double)f.QuadPart;    RNG &rng = theRNG();    double alpha = 1.f, gamma = 0;    int factor = 1;    for (int i = 0; i < LEN; i++){        factor += 10;        int m = 5 * factor, p = 10 * factor, n = 5 * factor;        Mat_<float> A(m, p, CV_32F), B(p, n, CV_32F), C = Mat::zeros(m, n, CV_32F);        rng.fill(A, RNG::NORMAL, 1, 100);//mean=1,stddev=100        rng.fill(B, RNG::NORMAL, 2, 50);        QueryPerformanceCounter(&time_start);        cv::gemm(A, B, alpha, C, gamma, C);        QueryPerformanceCounter(&time_over);        timeOpenCV[i] = (time_over.QuadPart - time_start.QuadPart) / dqFreq * 1000;//milliseconds        float *src1, *src2, *src3;        src1 = (float*)A.data;        src2 = (float*)B.data;        src3 = (float*)C.data;        QueryPerformanceCounter(&time_start);        cblas_sgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, m, n, p,            (float)alpha, src1, m, src2, p, (float)gamma, src3, m);        QueryPerformanceCounter(&time_over);        timeOpenBlas[i] = (time_over.QuadPart - time_start.QuadPart) / dqFreq * 1000;//milliseconds    }    for (int i = 0; i < LEN; i++){        cout << timeOpenCV[i] << " ";    }    cout << endl;    for (int i = 0; i < LEN; i++){        cout << timeOpenBlas[i] << " ";    }    system("pause");    return 0;}

得到的结果在MATLAB中显示如下:
这里写图片描述
这个是前10个结果的比对,可以看出:
1.OpenBlas第一次运行的时候需要很多时间,其实Opencv也有这个这个现象,第一次启动时运行时间要比第二次运行时间长点点。
2.当矩阵的维数增大时,Opencv所花的矩阵相乘时间成指数增长,而OpenBlas却保持得很好,从下面的30个数据的结果可以看出,OpenBlas所花的时间成线性增长,factor因子是成线性增长的,所以,OpenBlas中的时间复杂度是O(n),这时OpenBlas完胜OpenCV。
这里写图片描述

结论

1.Opencv中的矩阵乘法函数gemm只适应于矩阵维数小的情况,大概加估计的话,当矩阵阶数是1000以内时,Opencv可以1000ms内完成两个矩阵相乘。
2.OpenBlas适合处理高维矩阵相乘,对于小矩阵有点像杀鸡用牛刀,当矩阵维数为1500*3000时,仍然可以在500ms以内完成两个矩阵相乘。

当然,具体时间可能跟机器有些差别,本结论是程序在Release 32bit配置下运行在AMD3.5GHz,6核64位win7系统上的结果。
另外,Opencv中不支持gemv矩阵向量相乘运算。

转载请注明作者和出处:http://blog.csdn.net/CHIERYU 未经允许请勿用于商业用途

1 0
原创粉丝点击