原文链接:

http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/gpu/gpu-basics-similarity/gpu-basics-similarity.html

代码中有错误,关于GpuMat OpenCV代码中没有对其进行操作符运算的重载,所有编译的时候有错误。对于GpuMat的运算只能调用相关函数才行,后面我嫌麻烦就没有重写

<span style="font-size:18px;">// PSNR.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"#include <iostream>                   // Console I/O
#include <sstream>                    // String to number conversion#include <opencv2/core/core.hpp>      // Basic OpenCV structures
#include <opencv2/imgproc/imgproc.hpp>// Image processing methods for the CPU
#include <opencv2/highgui/highgui.hpp>// Read images
#include <opencv2/gpu/gpu.hpp>        // GPU structures and methodsusing namespace std;
using namespace cv;double getPSNR(const Mat& I1, const Mat& I2);      // CPU versions
Scalar getMSSIM( const Mat& I1, const Mat& I2);double getPSNR_GPU(const Mat& I1, const Mat& I2);  // Basic GPU versions
Scalar getMSSIM_GPU( const Mat& I1, const Mat& I2);struct BufferPSNR                                     // Optimized GPU versions
{   // Data allocations are very expensive on GPU. Use a buffer to solve: allocate once reuse later.gpu::GpuMat gI1, gI2, gs, t1,t2;gpu::GpuMat buf;
};
double getPSNR_GPU_optimized(const Mat& I1, const Mat& I2, BufferPSNR& b);struct BufferMSSIM                                     // Optimized GPU versions
{   // Data allocations are very expensive on GPU. Use a buffer to solve: allocate once reuse later.gpu::GpuMat gI1, gI2, gs, t1,t2;gpu::GpuMat I1_2, I2_2, I1_I2;vector<gpu::GpuMat> vI1, vI2;gpu::GpuMat mu1, mu2; gpu::GpuMat mu1_2, mu2_2, mu1_mu2; gpu::GpuMat sigma1_2, sigma2_2, sigma12; gpu::GpuMat t3; gpu::GpuMat ssim_map;gpu::GpuMat buf;
};
Scalar getMSSIM_GPU_optimized( const Mat& i1, const Mat& i2, BufferMSSIM& b);void help()
{cout<< "\n--------------------------------------------------------------------------" << endl<< "This program shows how to port your CPU code to GPU or write that from scratch." << endl<< "You can see the performance improvement for the similarity check methods (PSNR and SSIM)."  << endl<< "Usage:"                                                               << endl<< "./gpu-basics-similarity referenceImage comparedImage numberOfTimesToRunTest(like 10)." << endl<< "--------------------------------------------------------------------------"   << endl<< endl;
}int main(int argc, char *argv[])
{help(); Mat I1 = imread("swan1.jpg",1);           // Read the two imagesMat I2 = imread("swan2.jpg",1);if (!I1.data || !I2.data)           // Check for success{cout << "Couldn't read the image";return 0;}BufferPSNR bufferPSNR;BufferMSSIM bufferMSSIM;int TIMES; stringstream sstr("500"); sstr >> TIMES;double time, result;//------------------------------- PSNR CPU ----------------------------------------------------time = (double)getTickCount();    for (int i = 0; i < TIMES; ++i)result = getPSNR(I1,I2);time = 1000*((double)getTickCount() - time)/getTickFrequency();time /= TIMES;cout << "Time of PSNR CPU (averaged for " << TIMES << " runs): " << time << " milliseconds."<< " With result of: " <<  result << endl; //------------------------------- PSNR GPU ----------------------------------------------------time = (double)getTickCount();    for (int i = 0; i < TIMES; ++i)result = getPSNR_GPU(I1,I2);time = 1000*((double)getTickCount() - time)/getTickFrequency();time /= TIMES;cout << "Time of PSNR GPU (averaged for " << TIMES << " runs): " << time << " milliseconds."<< " With result of: " <<  result << endl;
/*//------------------------------- PSNR GPU Optimized--------------------------------------------time = (double)getTickCount();                                  // Initial callresult = getPSNR_GPU_optimized(I1, I2, bufferPSNR);time = 1000*((double)getTickCount() - time)/getTickFrequency();cout << "Initial call GPU optimized:              " << time  <<" milliseconds."<< " With result of: " << result << endl;time = (double)getTickCount();    for (int i = 0; i < TIMES; ++i)result = getPSNR_GPU_optimized(I1, I2, bufferPSNR);time = 1000*((double)getTickCount() - time)/getTickFrequency();time /= TIMES;cout << "Time of PSNR GPU OPTIMIZED ( / " << TIMES << " runs): " << time << " milliseconds." << " With result of: " <<  result << endl << endl; //------------------------------- SSIM CPU -----------------------------------------------------Scalar x;time = (double)getTickCount();    for (int i = 0; i < TIMES; ++i)x = getMSSIM(I1,I2);time = 1000*((double)getTickCount() - time)/getTickFrequency();time /= TIMES;cout << "Time of MSSIM CPU (averaged for " << TIMES << " runs): " << time << " milliseconds."<< " With result of B" << x.val[0] << " G" << x.val[1] << " R" << x.val[2] << endl; //------------------------------- SSIM GPU -----------------------------------------------------time = (double)getTickCount();    for (int i = 0; i < TIMES; ++i)x = getMSSIM_GPU(I1,I2);time = 1000*((double)getTickCount() - time)/getTickFrequency();time /= TIMES;cout << "Time of MSSIM GPU (averaged for " << TIMES << " runs): " << time << " milliseconds."<< " With result of B" << x.val[0] << " G" << x.val[1] << " R" << x.val[2] << endl; //------------------------------- SSIM GPU Optimized--------------------------------------------time = (double)getTickCount();    x = getMSSIM_GPU_optimized(I1,I2, bufferMSSIM);time = 1000*((double)getTickCount() - time)/getTickFrequency();cout << "Time of MSSIM GPU Initial Call            " << time << " milliseconds."<< " With result of B" << x.val[0] << " G" << x.val[1] << " R" << x.val[2] << endl; time = (double)getTickCount();    for (int i = 0; i < TIMES; ++i)x = getMSSIM_GPU_optimized(I1,I2, bufferMSSIM);time = 1000*((double)getTickCount() - time)/getTickFrequency();time /= TIMES;cout << "Time of MSSIM GPU OPTIMIZED ( / " << TIMES << " runs): " << time << " milliseconds."<< " With result of B" << x.val[0] << " G" << x.val[1] << " R" << x.val[2] << endl << endl; return 0;*/getchar();
}double getPSNR(const Mat& I1, const Mat& I2)
{Mat s1; absdiff(I1, I2, s1);       // |I1 - I2|s1.convertTo(s1, CV_32F);  // cannot make a square on 8 bitss1 = s1.mul(s1);           // |I1 - I2|^2Scalar s = sum(s1);         // sum elements per channeldouble sse = s.val[0] + s.val[1] + s.val[2]; // sum channelsif( sse <= 1e-10) // for small values return zeroreturn 0;else{double  mse =sse /(double)(I1.channels() * I1.total());double psnr = 10.0*log10((255*255)/mse);return psnr;}
}double getPSNR_GPU_optimized(const Mat& I1, const Mat& I2, BufferPSNR& b)
{    b.gI1.upload(I1);b.gI2.upload(I2);b.gI1.convertTo(b.t1, CV_32F);b.gI2.convertTo(b.t2, CV_32F);gpu::absdiff(b.t1.reshape(1), b.t2.reshape(1), b.gs);gpu::multiply(b.gs, b.gs, b.gs);double sse = gpu::sum(b.gs, b.buf)[0];if( sse <= 1e-10) // for small values return zeroreturn 0;else{double mse = sse /(double)(I1.channels() * I1.total());double psnr = 10.0*log10((255*255)/mse);return psnr;}
}double getPSNR_GPU(const Mat& I1, const Mat& I2)
{gpu::GpuMat gI1, gI2, gs, t1,t2; gI1.upload(I1);gI2.upload(I2);gI1.convertTo(t1, CV_32F);gI2.convertTo(t2, CV_32F);gpu::absdiff(t1.reshape(1), t2.reshape(1), gs); gpu::multiply(gs, gs, gs);Scalar s = gpu::sum(gs);double sse = s.val[0] + s.val[1] + s.val[2];if( sse <= 1e-10) // for small values return zeroreturn 0;else{double  mse =sse /(double)(gI1.channels() * I1.total());double psnr = 10.0*log10((255*255)/mse);return psnr;}
}Scalar getMSSIM( const Mat& i1, const Mat& i2)
{ const double C1 = 6.5025, C2 = 58.5225;/***************************** INITS **********************************/int d     = CV_32F;Mat I1, I2; i1.convertTo(I1, d);           // cannot calculate on one byte large valuesi2.convertTo(I2, d); Mat I2_2   = I2.mul(I2);        // I2^2Mat I1_2   = I1.mul(I1);        // I1^2Mat I1_I2  = I1.mul(I2);        // I1 * I2/*************************** END INITS **********************************/Mat mu1, mu2;   // PRELIMINARY COMPUTINGGaussianBlur(I1, mu1, Size(11, 11), 1.5);GaussianBlur(I2, mu2, Size(11, 11), 1.5);Mat mu1_2   =   mu1.mul(mu1);    Mat mu2_2   =   mu2.mul(mu2); Mat mu1_mu2 =   mu1.mul(mu2);Mat sigma1_2, sigma2_2, sigma12; GaussianBlur(I1_2, sigma1_2, Size(11, 11), 1.5);sigma1_2 -= mu1_2;GaussianBlur(I2_2, sigma2_2, Size(11, 11), 1.5);sigma2_2 -= mu2_2;GaussianBlur(I1_I2, sigma12, Size(11, 11), 1.5);sigma12 -= mu1_mu2;/ FORMULA Mat t1, t2, t3; t1 = 2 * mu1_mu2 + C1; t2 = 2 * sigma12 + C2; t3 = t1.mul(t2);              // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))t1 = mu1_2 + mu2_2 + C1; t2 = sigma1_2 + sigma2_2 + C2;     t1 = t1.mul(t2);               // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))Mat ssim_map;divide(t3, t1, ssim_map);      // ssim_map =  t3./t1;Scalar mssim = mean( ssim_map ); // mssim = average of ssim mapreturn mssim;
}Scalar getMSSIM_GPU( const Mat& i1, const Mat& i2)
{ const float C1 = 6.5025f, C2 = 58.5225f;/***************************** INITS **********************************/gpu::GpuMat gI1, gI2, gs1, t1,t2; gI1.upload(i1);gI2.upload(i2);gI1.convertTo(t1, CV_MAKE_TYPE(CV_32F, gI1.channels()));gI2.convertTo(t2, CV_MAKE_TYPE(CV_32F, gI2.channels()));vector<gpu::GpuMat> vI1, vI2; gpu::split(t1, vI1);gpu::split(t2, vI2);Scalar mssim;for( int i = 0; i < gI1.channels(); ++i ){gpu::GpuMat I2_2, I1_2, I1_I2; gpu::multiply(vI2[i], vI2[i], I2_2);        // I2^2gpu::multiply(vI1[i], vI1[i], I1_2);        // I1^2gpu::multiply(vI1[i], vI2[i], I1_I2);       // I1 * I2/*************************** END INITS **********************************/gpu::GpuMat mu1, mu2;   // PRELIMINARY COMPUTINGgpu::GaussianBlur(vI1[i], mu1, Size(11, 11), 1.5);gpu::GaussianBlur(vI2[i], mu2, Size(11, 11), 1.5);gpu::GpuMat mu1_2, mu2_2, mu1_mu2; gpu::multiply(mu1, mu1, mu1_2);   gpu::multiply(mu2, mu2, mu2_2);   gpu::multiply(mu1, mu2, mu1_mu2);   gpu::GpuMat sigma1_2, sigma2_2, sigma12; gpu::GaussianBlur(I1_2, sigma1_2, Size(11, 11), 1.5);//sigma1_2 = sigma1_2 - mu1_2;gpu::subtract(sigma1_2,mu1_2,sigma1_2);gpu::GaussianBlur(I2_2, sigma2_2, Size(11, 11), 1.5);//sigma2_2 = sigma2_2 - mu2_2;gpu::GaussianBlur(I1_I2, sigma12, Size(11, 11), 1.5);(Mat)sigma12 =(Mat)sigma12 - (Mat)mu1_mu2;//sigma12 = sigma12 - mu1_mu2/ FORMULA gpu::GpuMat t1, t2, t3; //         t1 = 2 * mu1_mu2 + C1;
//      t2 = 2 * sigma12 + C2;
//      gpu::multiply(t1, t2, t3);     // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))
//
//      t1 = mu1_2 + mu2_2 + C1;
//      t2 = sigma1_2 + sigma2_2 + C2;
//      gpu::multiply(t1, t2, t1);     // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))gpu::GpuMat ssim_map;gpu::divide(t3, t1, ssim_map);      // ssim_map =  t3./t1;Scalar s = gpu::sum(ssim_map);    mssim.val[i] = s.val[0] / (ssim_map.rows * ssim_map.cols);}return mssim;
}Scalar getMSSIM_GPU_optimized( const Mat& i1, const Mat& i2, BufferMSSIM& b)
{ int cn = i1.channels();const float C1 = 6.5025f, C2 = 58.5225f;/***************************** INITS **********************************/b.gI1.upload(i1);b.gI2.upload(i2);gpu::Stream stream;stream.enqueueConvert(b.gI1, b.t1, CV_32F);stream.enqueueConvert(b.gI2, b.t2, CV_32F);      gpu::split(b.t1, b.vI1, stream);gpu::split(b.t2, b.vI2, stream);Scalar mssim;for( int i = 0; i < b.gI1.channels(); ++i ){        gpu::multiply(b.vI2[i], b.vI2[i], b.I2_2, stream);        // I2^2gpu::multiply(b.vI1[i], b.vI1[i], b.I1_2, stream);        // I1^2gpu::multiply(b.vI1[i], b.vI2[i], b.I1_I2, stream);       // I1 * I2//gpu::GaussianBlur(b.vI1[i], b.mu1, Size(11, 11), 1.5, 0, BORDER_DEFAULT, -1, stream);//gpu::GaussianBlur(b.vI2[i], b.mu2, Size(11, 11), 1.5, 0, BORDER_DEFAULT, -1, stream);gpu::multiply(b.mu1, b.mu1, b.mu1_2, stream);   gpu::multiply(b.mu2, b.mu2, b.mu2_2, stream);   gpu::multiply(b.mu1, b.mu2, b.mu1_mu2, stream);   //gpu::GaussianBlur(b.I1_2, b.sigma1_2, Size(11, 11), 1.5, 0, BORDER_DEFAULT, -1, stream);//gpu::subtract(b.sigma1_2, b.mu1_2, b.sigma1_2, stream);//b.sigma1_2 -= b.mu1_2;  - This would result in an extra data transfer operation//gpu::GaussianBlur(b.I2_2, b.sigma2_2, Size(11, 11), 1.5, 0, BORDER_DEFAULT, -1, stream);//gpu::subtract(b.sigma2_2, b.mu2_2, b.sigma2_2, stream);//b.sigma2_2 -= b.mu2_2;//gpu::GaussianBlur(b.I1_I2, b.sigma12, Size(11, 11), 1.5, 0, BORDER_DEFAULT, -1, stream);//gpu::subtract(b.sigma12, b.mu1_mu2, b.sigma12, stream);//b.sigma12 -= b.mu1_mu2;//here too it would be an extra data transfer due to call of operator*(Scalar, Mat)gpu::multiply(b.mu1_mu2, 2, b.t1, stream); //b.t1 = 2 * b.mu1_mu2 + C1; //gpu::add(b.t1, C1, b.t1, stream);gpu::multiply(b.sigma12, 2, b.t2, stream); //b.t2 = 2 * b.sigma12 + C2; //gpu::add(b.t2, C2, b.t2, stream);     gpu::multiply(b.t1, b.t2, b.t3, stream);     // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))//gpu::add(b.mu1_2, b.mu2_2, b.t1, stream);//gpu::add(b.t1, C1, b.t1, stream);//gpu::add(b.sigma1_2, b.sigma2_2, b.t2, stream);//gpu::add(b.t2, C2, b.t2, stream);gpu::multiply(b.t1, b.t2, b.t1, stream);     // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))        gpu::divide(b.t3, b.t1, b.ssim_map, stream);      // ssim_map =  t3./t1;stream.waitForCompletion();Scalar s = gpu::sum(b.ssim_map, b.buf);    mssim.val[i] = s.val[0] / (b.ssim_map.rows * b.ssim_map.cols);}return mssim;
}</span>

实现效果:

转载于:https://www.cnblogs.com/wuyida/p/6301427.html

基于opencv的gpu与cpu对比程序,代码来自opencv的文档中相关推荐

  1. nopi word to html,C# 基于NPOI+Office COM组件 实现20行代码在线预览文档(word,excel,pdf,txt,png)...

    由于项目需要,需要一个在线预览office的功能,小编一开始使用的是微软提供的方法,简单快捷,但是不符合小编开发需求, 就另外用了:将文件转换成html文件然后预览html文件的方法.对微软提供的方法 ...

  2. python kivy显示图片_python基于Kivy写一个图形桌面时钟程序代码示例

    本篇文章小编给大家分享一下python基于Kivy写一个图形桌面时钟程序代码示例,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. Kivy 是一个开源的 ...

  3. 基于stc89c51单片机的温控风扇(程序代码+原理图)

    基于stc89c51单片机的温控风扇(程序代码+原理图) 自动模式下,通过读取ds18b20的温度,并且通过红外人体感应,判断是否有人,如果有人就智能自动设置风扇的pwm输出,达到智能调温的作用,如果 ...

  4. 基于智能家居c语言程序代码,基于单片机的智能家居系统设计(附程序代码)

    基于单片机的智能家居系统设计(附程序代码)(任务书,开题报告,外文翻译,论文10000字) 摘要 基于近年来通信电子技术的高速发展,使得一些原来可望不可及的事关民生的技术变为可能,条件允许的情况下,人 ...

  5. 基于sklearn的朴素贝叶斯_朴素贝叶斯分类实战:对文档进行分类

    朴素贝叶斯分类最适合的场景就是文本分类.情感分析和垃圾邮件识别.其中情感分析和垃圾邮件识别都是通过文本来进行判断.所以朴素贝叶斯也常用于自然语言处理 NLP 的工具. sklearn 机器学习包 sk ...

  6. 基于Java毕业设计写手管理平台源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计写手管理平台源码+系统+mysql+lw文档+部署软件 基于Java毕业设计写手管理平台源码+系统+mysql+lw文档+部署软件 本源码技术栈: 项目架构:B/S架构 开发语言: ...

  7. 基于JAVA第二课堂选课系统计算机毕业设计源码+系统+lw文档+部署

    基于JAVA第二课堂选课系统计算机毕业设计源码+系统+lw文档+部署 基于JAVA第二课堂选课系统计算机毕业设计源码+系统+lw文档+部署 本源码技术栈: 项目架构:B/S架构 开发语言:Java语言 ...

  8. 基于java点播影院运营系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署

    基于java点播影院运营系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署 基于java点播影院运营系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署 本源码技术栈: ...

  9. 基于Java毕业设计缘梦书屋网站源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计缘梦书屋网站源码+系统+mysql+lw文档+部署软件 基于Java毕业设计缘梦书屋网站源码+系统+mysql+lw文档+部署软件 本源码技术栈: 项目架构:B/S架构 开发语言: ...

最新文章

  1. CentOS的el5, el6, el7代表什么
  2. 码云gitee最大文件限制
  3. get_live2d获取不到500_有人手机收不到验证码?警方打掉一“薅羊毛”产业链,全国已有570多万台手机被控制……...
  4. Linux文件查找find和locate
  5. 你不得不了解 Helm 3 中的 5 个关键新特性
  6. [python爬虫] Selenium常见元素定位方法和操作的学习介绍(转载)
  7. 380免费云存储_三款功能强大的云盘软件,完全替代百度云与腾讯云
  8. (19)Xilinx PCIE中断理论(学无止境)
  9. netif_receive_skb 函数解析
  10. VMware Workstation 无法与 Windows XP \ Windows 7 \ Windows 8 进行共享文件夹。
  11. eclipse 批量 查询 替换
  12. ibm服务器安装aix系统,IBM AIX 系统安装详细过程及注意事项
  13. Verilog CIC 滤波器设计(代码自取)
  14. 如何提供网络冗余和稳定连接
  15. 请问在深圳做美工的工资多少
  16. outlook 2016 英文版 撤回邮件
  17. Maximo 人员- 应用程序导入,公共操作怎么配置,求大神指点,万分感谢
  18. html excel导出的路径,html 导出多个excel表格数据-如何将html页面中的表格导出到excel表格...
  19. PS PhotoShop CS5 CS6 序列号 安装
  20. vivo全球商城架构演进之路

热门文章

  1. JS高级——纯函数、柯里化(手写自动柯里化函数)、组合函数(手写自动组合函数)
  2. Mongoose 中使用 populate 实现关联查询
  3. LeetCode 1664. 生成平衡数组的方案数(前缀和+后缀和)
  4. LeetCode 1641. 统计字典序元音字符串的数目(DP)
  5. LeetCode 1553. 吃掉 N 个橘子的最少天数(BFS)
  6. LeetCode 758. 字符串中的加粗单词(Trie树)
  7. LeetCode 1276. 不浪费原料的汉堡制作方案(解方程)
  8. afreecatv 回放下载_行车记录仪怎么看回放?行车记录仪停车后能自动录像吗
  9. python的指针跟c的区别_ctypes中的LP_x*指针和*p指针有什么区别?(以及与结构的奇怪交互)...
  10. python中的匿名函数lambda