转载请注明出处:

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. tiny xml 使用总结

    这几天在埋头写自己的3D文件浏览器(稍后发布),突发奇想的要把自己的内部格式转化成XML,于是,把以前在研究所时用过的ExPat翻了出来.ExPat是基于事件的XML解释器,速度挺快的,但结构方面有点 ...

  2. beini系列_2_beini装入虚拟机

  3. .Net 插入数据MySql数据库,中文乱码解决问题

    1, 修改mysql根目录下配置文件my.ini,在[client]节点下添加default-character-set=utf8 ,在[mysqld]节点下添加character_set_serve ...

  4. 拉姆达表达式 追加 条件判断 Expression<Func<T, bool>>

    public static class PredicateBuilder { /// <summary> /// 机关函数应用True时:单个AND有效,多个AND有效:单个OR无效,多个 ...

  5. [Codeforces Round #247 (Div. 2)] A. Black Square

    A. Black Square time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  6. C语言实现的OOP

    我倒不是为了OOP而OOP,实在是OOP的一些特征,例如封装,多态其实是软件工程思想,这些思想不分语言,遵循了这些思想可以使得程序更有弹性,更易修改和维护,避免僵化,脆弱 shape.h 该文件定义的 ...

  7. 使用 Mockito 单元测试 – 教程

    tanyuanji@126.com 版本历史 - - - - 使用 Mockito 进行测试 该教程主要讲解 Mockito 框架在Eclipse IDE 中的使用   目录 tanyuanji@12 ...

  8. QDialog 添加最大化、最小化按钮和关闭按钮,并且要正常显示

    在使用QDialog时,默认情况下只有“这是什么”和“关闭”按钮(不知道为什么QT要这么做),但是我们习惯有最大化和最小化按钮.本文介绍如何在该模式下如何设置. 新建一个QDialog工程,然后打开D ...

  9. 我的Android4.3新书即将上市,谢谢大家的支持

    首先感谢清华大学.电子工业.机械工业.人民邮电等各大出版社对本书的肯定.我想说中国的IT业如果没有你们的辛勤工作,是不会发展得这么快的.经过再三权衡,本书将选择人民邮电出版社于近几个月在全国出版发行. ...

  10. Windows下连接php5.3+sql server2008

    php连接sql server真是一件闹心的事, 折腾了许久,今天有了点起色,还是不错的. mssql extension is not available anymore on Windows wi ...