转载请注明出处:

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. jade的基本语法

    - for (var i=0;i<3;i++) li scnu-learn //这里的=,默认会转义内容 p= "Welcome scnu <strong>good< ...

  2. apache 出现Index of /的页面解决

    在apache安装文件中找到http.conf配置文件,打开找到 Options Indexes FollowSymLinks 这行,在Indexes前加一个-(减号),也就是该完之后是这样: Opt ...

  3. windows安装composer方法和使用方法

    最近在学习yii2的框架的相关知识,对于yii2的许多新特性,最好还是去查看官网文档最好,如果有中文翻译的网站就更好了. 学习yii2的第一个门槛就是得安装composer这个依赖管理工具(但目前我认 ...

  4. ASP转PHP手记

    打算将动易网站管理系统移植到PHP环境中,寻寻觅觅了很多PHP内容管理网站,发现网上有动易转PHPCMS的代码,所以就拿定注意用PHPCMS的在google上找到一转换程序,动手做来还成功了,现将此次 ...

  5. 为什么1Byte=8bit

    Byte是字节的意思,而字节在早期计算机内部是用标准ASCII码来表示的根据当时情况确定至多有128种需要表示的字符(当时是IBM的标准,现在普遍是255),也就是2的7次方用二进制的0和1来表示就需 ...

  6. nginx日志管理与限速

    1.日志简介nginx日志主要有两种:访问日志和错误日志.访问日志主要记录客户端访问nginx的每一个请求,格式可以自定义:错误日志主要记录客户端访问nginx出错时的日志,格式不支持自定义.两种日志 ...

  7. Netbeans7.4下搭建struts2.3.16

    一:所需要的jar包如下: 在WEB-INF目录下新建一个lib文件夹将jar包复制到里面: 在这里要注意将jar包导入lib目录里还不可以,在这里与MyEclipse不同.在项目上右键属性-> ...

  8. 单片机 认识HEX文件

    看过几篇常用指令的用法后,我们换换口味,介绍一下Intel 原厂所公布的HEX文件标准格式,相信经过本文的介绍,一定可以让您对8051的操作有更进一步的认识.以下是一个程序经编译器编译后所得到的HEX ...

  9. 通过Excel来集中管理资源文件

     在支持双语或多语种项目中,常常需要编辑多个文件来添加资源项,感觉比较繁琐,所以想做一个可以集中管理资源文件的工具.借助Excel,使用Excel来记录,并且通过Excel可以进行分页分模块来规划 ...

  10. Axure设计分析作业-实例解析

    本文转载自人人都谁产品经理,作者完全使用Axure做了这一个产品需求文档.文档地址:http://1passwordmanager.sinaapp.com/ 大家可以先睹为快.这个PRD完全使用axu ...