转载请注明出处:

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. 图片自动转换效果 jquery

    http://www.16sucai.com/uploadfile/show5/switchable01/switchable/ <div class="maxpSlid" ...

  2. Server2008R2:由于没有远程桌面授权服务器可以提供许可证,.....错误的解决 ---设计师零张

    一直使用远程桌面连接一台windows2008server服务器,今天突然报错,连不上了:   “由于没有远程桌面授权服务器可以提供许可证,远程会话被中断.请跟服务器管理员联系.”       由于是 ...

  3. nginx网站架构优化思路(原)

    本人接触的优化主要分为三大类 黑体的为本模块下的重点  ---------------安全优化 安全在生产场景中是第一位的 1.1 站点目录权限的优化 (修改权限755 644 所属用户root,需要 ...

  4. [android]-如何在向服务器发送request时附加已保存的cookie数据

    [android]-如何在向服务器发送request时附加已保存的cookie数据 应用场景:在开发android基于手机端+服务器端的应用时,登陆->获取用户信息->获取授权用户相关业务 ...

  5. SQL 如何表示引号

    SELECT ename || '''' || ' 的工作是 ' || ' ' || job || '''' AS msg FROM emp WHERE deptno = 10; ' '' ' 第一个 ...

  6. 【转】各个层次的gcc警告 #pragma GCC diagnostic ignored "-Wunused-parameter" --不错

    原文网址:http://blog.csdn.net/lizzywu/article/details/9419145 各个层次的gcc警告从上到下覆盖 变量(代码)级:指定某个变量警告 int a __ ...

  7. Linux web性能优化

    1,

  8. javascript的事件处理

        首先了解一下什么是事件?事件是web浏览器通知应用程序发生了什么事情.我们可以通过一些方式注册事件用来监听一些我们需要处理的事件.事件包含一下一些属性:     事件类型:用来说明是什么类型事 ...

  9. Redis 该选择哪种持久化配置

    这个标题或许会让你想起<黑客帝国>里经典的台词,你要选择蓝色药丸,还是红色药丸? Redis 是我们重度使用的一个开源软件,对它的持久化配置做一番相对深入的总结,是值得的.目前它有两种主流 ...

  10. python list 中找连续的数字(由网友处学习)

    # -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #学习这个要求的:http://wsky.org/archives/ ...