众所周知,Gpu加速技术对图像处理具有很大的影响,在前面的博客中通过对比验证了Gpu加速技术对图像滤波的高效率。但是Gpu技术并不是万能的,本文通过比较发现Gpu计算直方图的效率并没有传统计算方法效率高。下面表格是对比结果,时间是通过运行20次求平均值而得,后面给出相应的比较代码。由结果可以看出Cpu计算直方图是运行效率更高,当对图片数据库进行训练时,如果有5000幅图片需要处理,采用Cpu计算方式可以节省75分钟左右的时间,节省的时间还是相当可观的。
方式 | Cpu内存 | Gpu内存 |
效率 | 0.855328s | 1.71659s |
利用histEven函数在Gpu内存中计算直方图,运行20次后平均运行时间为1.71659s。下面的代码有的头文件不是必须的。
#include <stdio.h> #include <tchar.h> #include <afxwin.h> #include <opencv.hpp> #include <opencv2/gpu/gpu.hpp> #include <fstream> #include <algorithm> #include "my_function.h" #include <memory> #include<vector> #define pi 3.14156 #define CLASSNUM 102 #define TR_NUM 15 #define TE_NUM 15 using namespace std ; using namespace cv ; using namespace cv::gpu; int _tmain(int argc, _TCHAR* argv[]) { Mat img = imread("sunflower.jpg",0);//读取图 像 文件 Ptr<FilterEngine_GPU> FDct[11][11]; GpuMat dst_gpu, src_gpu; Mat kd; Mat dst; double fmin,fmax; DctFilter(kd,11);//建立DCT变换滤波器 for(int i=0;i<11;i++) for(int j=0;j<11;j++) FDct[i][j]= createSeparableLinearFilter_GPU(CV_8U,CV_32F, kd.col(i), kd.col(j));//构造Opencv滤波器类对象 double t = (double)cvGetTickCount(); src_gpu.upload(img);//上传数据到Gpu内存中 for(int k=0;k<20;k++) { for(int u=0;u<11;u++) for(int v=0;v<11;v++) { FDct[u][v]->apply(src_gpu,dst_gpu); //执行滤波操作 normalize(dst_gpu,dst_gpu,255.0,0.0,NORM_MINMAX);//滤波后矩阵数值范围规范化到0~255 dst_gpu.convertTo(dst_gpu,CV_8U); //histEven函数需要CV_8U, CV_16U, or CV_16S数据类型 histEven(dst_gpu,dst_gpu,10,0,255);//在Gpu内存中计算直方图 normalize(dst_gpu,dst_gpu,1.0,0.0,NORM_MINMAX);//对直方图统计值规范化到0~1之间 dst_gpu.download(dst);//从Gpu内存中读取数据 } } t=(double)cvGetTickCount()-t; printf( "run time = %gs\n", t/(cvGetTickFrequency()*1000000)/20 ); system("pause"); }
#include <stdio.h> #include <tchar.h> #include <afxwin.h> #include <opencv.hpp> #include <opencv2/gpu/gpu.hpp> #include <fstream> #include <algorithm> #include "my_function.h" #include <memory> #include<vector> #define pi 3.14156 #define CLASSNUM 102 #define TR_NUM 15 #define TE_NUM 15 using namespace std ; using namespace cv ; using namespace cv::gpu; int _tmain(int argc, _TCHAR* argv[]) { Mat img = imread("sunflower.jpg",0);//读取图 像 文件 Ptr<FilterEngine_GPU> FDct[11][11]; GpuMat dst_gpu, src_gpu; Mat kd; Mat dst; double fmin,fmax; DctFilter(kd,11);//建立DCT变换滤波器 for(int i=0;i<11;i++) for(int j=0;j<11;j++) FDct[i][j]= createSeparableLinearFilter_GPU(CV_8U,CV_32F, kd.col(i), kd.col(j));//构造Opencv滤波器类对象 double t = (double)cvGetTickCount(); src_gpu.upload(img);//上传数据到Gpu内存中 for(int k=0;k<20;k++) { for(int u=0;u<11;u++) for(int v=0;v<11;v++) { FDct[u][v]->apply(src_gpu,dst_gpu);//执行滤波操作 dst_gpu.download(dst);//从Gpu内存中读取数据 minMaxIdx(dst,&fmin,&fmax); dst.convertTo(dst,CV_8U,255.0/(fmax-fmin),-255.0*fmin/(fmax-fmin)); //滤波后矩阵数值范围规范化到0~255 int histSize[] = {10}; float hranges[] = { 0, 256 }; const float* ranges[] = { hranges }; MatND hist; int channels[] = {0}; calcHist( &dst, 1, channels, Mat(), // do not use mask hist, 1, histSize, ranges, true, // the histogram is uniform false ); double maxVal=0; minMaxLoc(hist, 0, &maxVal, 0, 0); hist=hist.mul(1.0f/maxVal); //对直方图统计值规范化到0~1之间 } } t=(double)cvGetTickCount()-t; printf( "run time = %gs\n", t/(cvGetTickFrequency()*1000000)/20.0 ); system("pause"); }
原文:http://blog.csdn.net/kxuehen/article/details/42028991