转载请注明出处:

http://www.cnblogs.com/darkknightzh/p/5462631.html

参考网址:

https://software.intel.com/zh-cn/node/504170

https://software.intel.com/en-us/node/599808

https://software.intel.com/en-us/node/504340

 #include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
#include <ipp.h> enum ConvolutionType // 卷积时参数的类型
{
CONVOLUTION_FULL, // 卷积时的参数,和 matlab 的 full 一致
CONVOLUTION_SAME, // 卷积时的参数,和 matlab 的 same 一致
CONVOLUTION_VALID // 卷积时的参数,和 matlab 的 valid 一致
}; void Conv2IPP(Mat& convRes, const Mat& imgIn, const Mat& kernelIn, ConvolutionType type, int ddepth)
{
Mat img = imgIn.clone(), kernel = kernelIn.clone();
const IppiSize imgSize = { img.cols, img.rows };
const IppiSize kerSize = { kernel.cols, kernel.rows }; if (CV_32FC1 != img.type())
{
img.convertTo(img, CV_32FC1); // ipp的库支持8u,16s,32f这几种精度的数据的卷积
}
if (CV_32FC1 != kernel.type())
{
kernel.convertTo(kernel, CV_32FC1);
} int nConvResW = img.cols + kernel.cols - ;
int nConvResH = img.rows + kernel.rows - ;
// 如果直接声明Mat的变量,并在ippiConv_32f_C1R中传递.data缓冲区的话,程序会崩溃,因而只能先加一个临时变量
float *pConvRes = new float[nConvResW * nConvResH]; // ippiROIFull改为ippiROIValid或者ippiROISame对应matlab响应的参数。不能直接改,否则结果不对。具体怎么改,暂时不清楚。
IppEnum funCfgFull = (IppEnum)(ippAlgAuto | ippiROIFull | ippiNormNone);
int bufSizeFull;
IppStatus status = ippiConvGetBufferSize(imgSize, kerSize, ipp32f, , funCfgFull, &bufSizeFull);
Ipp8u* pBuffer = ippsMalloc_8u(bufSizeFull); ippiConv_32f_C1R((Ipp32f*)img.data, img.step, imgSize, (Ipp32f*)kernel.data, kernel.step, kerSize,
pConvRes, nConvResW * , funCfgFull, pBuffer); // 此处应该使用nConvResW * 4 Mat matConvResTemp(nConvResH, nConvResW, CV_32FC1);
memcpy(matConvResTemp.data, pConvRes, sizeof(float)* nConvResH * nConvResW); Rect r;
switch (type)
{
case CONVOLUTION_FULL: // full
r = Rect(, , matConvResTemp.cols, matConvResTemp.rows);
break;
case CONVOLUTION_SAME: // same
r = Rect((kernel.cols + 0.5) / , (kernel.rows + 0.5) / , img.cols, img.rows);
break;
case CONVOLUTION_VALID: // valid
r = Rect((kernel.cols + 0.5) / , (kernel.rows + 0.5) / , img.cols - kernel.cols + , img.rows - kernel.rows + );
break;
default: // same
r = Rect((kernel.cols + 0.5) / , (kernel.rows + 0.5) / , img.cols, img.rows);
break;
} matConvResTemp(r).convertTo(convRes, ddepth, , ); // ddepth为CV_32FC1等类型 ippsFree(pBuffer);
delete[] pConvRes;
pConvRes = nullptr;
}

说明:不确定的有2处:

1. 此程序计算卷积还是相关?感觉像是相关而非卷积(之前写过的程序计算相关,此处和之前的结果总体上相似。理论上卷积是核需要上下左右镜像的,这个地方不确定)

ps:应该是卷积。

2. CONVOLUTION_FULL没有问题,CONVOLUTION_SAME不确定矩形框是否正确,CONVOLUTION_VALID也不确定是否正确。实际上对于后两者,可以将标志funCfgFull从ippiROIFull改为ippiROISame或者ippiROIValid,不过卷积的缓冲区pConvRes需要相应的改变大小。还有,如果直接改标志的话,卷积的结果不正确。不清楚什么原因。

ps:当使用ippiROISame时,计算到的bufSizeFull的值为0,因而卷积的结果不正确。不明白为什么。

150506更新:

在第三个参考网址中,发现了另一个函数ippiCrossCorrNorm_32f_C1R,用于计算相关。可以选用ippiROISame参数。

 Mat Conv2IPPSame(const Mat& imgIn, const Mat& kernelIn)
{
Mat img = imgIn.clone(), kernel = kernelIn.clone();
const IppiSize imgSize = { img.cols, img.rows };
const IppiSize kerSize = { kernel.cols, kernel.rows }; if (CV_32FC1 != img.type())
{
img.convertTo(img, CV_32FC1);
}
if (CV_32FC1 != kernel.type())
{
kernel.convertTo(kernel, CV_32FC1);
} int nConvResW = img.cols;
int nConvResH = img.rows;
float *pConvRes = new float[nConvResW * nConvResH]; int bufSize;
IppEnum funCfg = (IppEnum)(ippAlgAuto | ippiROISame | ippiNormNone);
IppStatus status = ippiCrossCorrNormGetBufferSize(imgSize, kerSize, funCfg, &bufSize);
Ipp8u* pBuffer = ippsMalloc_8u(bufSize); ippiCrossCorrNorm_32f_C1R((Ipp32f*)img.data, img.step, imgSize, (Ipp32f*)kernel.data, kernel.step, kerSize,
pConvRes, nConvResW * , funCfg, pBuffer); Mat matConvRes(nConvResH, nConvResW, CV_32FC1);
memcpy(matConvRes.data, pConvRes, sizeof(float)* nConvResH * nConvResW); ippsFree(pBuffer);
delete[] pConvRes;
pConvRes = nullptr; return matConvRes;
}

从参考网址3中可以看到,ippiNormNone是计算相关的意思。

需要注意的是,第二个程序是计算相关的程序,而非卷积。和matlab的程序对比测试,发现第一个程序结果和卷积的结果相似,第二个程序的结果和相关的结果相似。

(原)使用intel的ipp库计算卷积及相关的更多相关文章

  1. (原)配置vs2013使用intel的IPP库

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5473890.html 参考网址: https://software.intel.com/en-us/n ...

  2. IPP库下FFT的基本实现

    首先感谢韩昊同学,他的傅里叶分析入门给我们对数学公式不熟悉的人了解傅里叶算法打开了一扇窗户,其原文发表于知乎:https://zhuanlan.zhihu.com/p/19763358 在了解其基本原 ...

  3. 图像卷积、相关以及在MATLAB中的操作

    图像卷积.相关以及在MATLAB中的操作 2016年7月11日 20:34:35, By ChrisZZ 区分卷积和相关 图像处理中常常需要用一个滤波器做空间滤波操作.空间滤波操作有时候也被叫做卷积滤 ...

  4. (原+转)使用opencv的DFT计算卷积

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5462665.html 参考网址: http://blog.csdn.net/lichengyu/art ...

  5. BLAS 与 Intel MKL 数学库

    0. BLAS BLAS(Basic Linear Algebra Subprograms)描述和定义线性代数运算的规范(specification),而不是一种具体实现,对其的实现包括: AMD C ...

  6. 利用python库计算person相关系数

    使用numpy库,可以实现person相关系数的计算,例如对于矩阵a. a Out[235]: array([[1, 1, 2, 2, 3], [2, 2, 3, 3, 5], [1, 4, 2, 2 ...

  7. Python:raschii库计算任意阶数Stokes波

    Stokes五阶波 最近发现一个很有用的Stokes波计算Python库,raschii官方说明,可以计算任意阶数,不同水深下的Stokes波,简单做了下测试,测试结果与脚本如下 Python 脚本 ...

  8. Intel 编译Boost库

    C:\Windows\SysWOW64\cmd.exe /E:ON /V:ON /K ""C:\Program Files (x86)\Intel\Composer XE 2013 ...

  9. Python datetime库计算两个时间点之间的分钟(秒、天)数

    计算两个时间点之间的分钟数 import datetime def minNums(startTime, endTime): '''计算两个时间点之间的分钟数''' # 处理格式,加上秒位 start ...

随机推荐

  1. (原)ubuntu安装libtbb.so.2

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6098132.html 参考网址: https://launchpad.net/ubuntu/+sour ...

  2. phpMyAdmin中mysql的创建数据库时的编码的问题

    转载自新浪博客    Sean 一. mysql中utf8编码的utf8_bin,utf8_general_cs,utf8_general_ci的区别 utf8_general_ci 不区分大小写,这 ...

  3. 什么是dtd文件,为什么需要dtd

    DTD为英文Document Type Definition,中文意思为"文档类定义".DTD肩负着两重任务:一方面它帮助你编写合法的代码,另一方面它让浏览器正确地显示器代码.也许 ...

  4. Linux 下的下载文件命令

    普通文件只需 wget  fileAddr 下载带有登录验证的文件 [chen@localhost Downloads]$ wget --user='av\bname' --ask-password ...

  5. Hibernate逆向工程全过程

    前提你已经创建好了数据库,按如下操作进行: 1.添加hibernate.cfg.xml 在src下-->new-->other--->hibernate-->选择“Hibern ...

  6. 试用mysql的infobright引擎

               海量数据分析处理,向来比较头疼费劲,特别是项目资金不允许的情况下,都是优先考虑开源软件,2007使用mysql,2009年尝试greenplum(公司最终选用oracle),20 ...

  7. 转:helloworld:一个完整的WCF案例

    原文地址:http://blog.csdn.net/mane_yao/article/details/5852845 WCF的ABC: A代表Address-where(对象在哪里)B代表Bindin ...

  8. Node.js 和Socket.IO 实现chat WEBIM

    socket官方:   http://socket.io/  需求:实现WEB IM功能,数据从服务器PUSH  不是PULL  websocket是基于HTML5的新特性,不兼容IE6,7,8 .. ...

  9. MongoDB GUI管理工具Mongo VUE

    一.前言 现在越来越多的公司开始采用非关系数据库了,并且很多公司的面试都要求面试 者有MongoDB的使用经验,至于非关系数据库与关系型数据库之间的区别大家可以自行百度.但是作为程序员的我们,既然大部 ...

  10. 【HDU1856】More is better(并查集基础题)

    裸并查集,但有二坑: 1.需要路径压缩,不写的话会TLE 2.根据题目大意,如果0组男孩合作的话,应该最大的子集元素数目为1.所以res初始化为1即可. #include <iostream&g ...