Opencv直方图计算是否需要Gpu加速?

        众所周知,Gpu加速技术对图像处理具有很大的影响,在前面的博客中点击打开链接通过对比验证了Gpu加速技术对图像滤波的高效率。但是Gpu技术并不是万能的,本文通过比较发现Gpu计算直方图的效率并没有传统计算方法效率高。下面表格是对比结果,时间是通过运行20次求平均值而得,后面给出相应的比较代码。由结果可以看出Cpu计算直方图是运行效率更高,当对图片数据库进行训练时,如果有5000幅图片需要处理,采用Cpu计算方式可以节省75分钟左右的时间,节省的时间还是相当可观的。

Gpu与Cpu计算直方图效率对比
方式Cpu内存Gpu内存
效率0.855328s1.71659s

测试图片如下所示,大小为400*300,在测试前程序中会转为灰度图。


利用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");
}

利用 calcHist 函数在电脑内存中计算直方图,运行20次后平均运行时间为0.855328s。下面的代码有的头文件不是必须的。

#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");
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值