博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(原)使用intel的ipp库计算卷积及相关
阅读量:5160 次
发布时间:2019-06-13

本文共 4490 字,大约阅读时间需要 14 分钟。

转载请注明出处:

参考网址:

 

1 #include 
2 #include
3 #include
4 using namespace cv; 5 #include
6 7 enum ConvolutionType // 卷积时参数的类型 8 { 9 CONVOLUTION_FULL, // 卷积时的参数,和 matlab 的 full 一致10 CONVOLUTION_SAME, // 卷积时的参数,和 matlab 的 same 一致11 CONVOLUTION_VALID // 卷积时的参数,和 matlab 的 valid 一致12 };13 14 void Conv2IPP(Mat& convRes, const Mat& imgIn, const Mat& kernelIn, ConvolutionType type, int ddepth)15 {16 Mat img = imgIn.clone(), kernel = kernelIn.clone();17 const IppiSize imgSize = { img.cols, img.rows };18 const IppiSize kerSize = { kernel.cols, kernel.rows };19 20 if (CV_32FC1 != img.type())21 {22 img.convertTo(img, CV_32FC1); // ipp的库支持8u,16s,32f这几种精度的数据的卷积23 }24 if (CV_32FC1 != kernel.type())25 {26 kernel.convertTo(kernel, CV_32FC1);27 }28 29 int nConvResW = img.cols + kernel.cols - 1;30 int nConvResH = img.rows + kernel.rows - 1;31 // 如果直接声明Mat的变量,并在ippiConv_32f_C1R中传递.data缓冲区的话,程序会崩溃,因而只能先加一个临时变量32 float *pConvRes = new float[nConvResW * nConvResH]; 33 34 // ippiROIFull改为ippiROIValid或者ippiROISame对应matlab响应的参数。不能直接改,否则结果不对。具体怎么改,暂时不清楚。35 IppEnum funCfgFull = (IppEnum)(ippAlgAuto | ippiROIFull | ippiNormNone); 36 int bufSizeFull;37 IppStatus status = ippiConvGetBufferSize(imgSize, kerSize, ipp32f, 1, funCfgFull, &bufSizeFull);38 Ipp8u* pBuffer = ippsMalloc_8u(bufSizeFull);39 40 ippiConv_32f_C1R((Ipp32f*)img.data, img.step, imgSize, (Ipp32f*)kernel.data, kernel.step, kerSize,41 pConvRes, nConvResW * 4, funCfgFull, pBuffer); // 此处应该使用nConvResW * 442 43 Mat matConvResTemp(nConvResH, nConvResW, CV_32FC1);44 memcpy(matConvResTemp.data, pConvRes, sizeof(float)* nConvResH * nConvResW);45 46 Rect r;47 switch (type)48 {49 case CONVOLUTION_FULL: // full50 r = Rect(0, 0, matConvResTemp.cols, matConvResTemp.rows);51 break;52 case CONVOLUTION_SAME: // same53 r = Rect((kernel.cols + 0.5) / 2, (kernel.rows + 0.5) / 2, img.cols, img.rows);54 break;55 case CONVOLUTION_VALID: // valid56 r = Rect((kernel.cols + 0.5) / 2, (kernel.rows + 0.5) / 2, img.cols - kernel.cols + 1, img.rows - kernel.rows + 1);57 break;58 default: // same59 r = Rect((kernel.cols + 0.5) / 2, (kernel.rows + 0.5) / 2, img.cols, img.rows);60 break;61 }62 63 matConvResTemp(r).convertTo(convRes, ddepth, 1, 0); // ddepth为CV_32FC1等类型64 65 ippsFree(pBuffer);66 delete[] pConvRes;67 pConvRes = nullptr;68 }

说明:不确定的有2处:

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

ps:应该是卷积。

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

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

 

150506更新:

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

1 Mat Conv2IPPSame(const Mat& imgIn, const Mat& kernelIn) 2 { 3     Mat img = imgIn.clone(), kernel = kernelIn.clone(); 4     const IppiSize imgSize = { img.cols, img.rows }; 5     const IppiSize kerSize = { kernel.cols, kernel.rows }; 6  7     if (CV_32FC1 != img.type()) 8     { 9         img.convertTo(img, CV_32FC1);10     }11     if (CV_32FC1 != kernel.type())12     {13         kernel.convertTo(kernel, CV_32FC1);14     }15 16     int nConvResW = img.cols;17     int nConvResH = img.rows;18     float *pConvRes = new float[nConvResW * nConvResH];19 20     int bufSize;21     IppEnum funCfg = (IppEnum)(ippAlgAuto | ippiROISame | ippiNormNone);22     IppStatus status = ippiCrossCorrNormGetBufferSize(imgSize, kerSize, funCfg, &bufSize);23     Ipp8u* pBuffer = ippsMalloc_8u(bufSize);24 25     ippiCrossCorrNorm_32f_C1R((Ipp32f*)img.data, img.step, imgSize, (Ipp32f*)kernel.data, kernel.step, kerSize,26         pConvRes, nConvResW * 4, funCfg, pBuffer);27 28     Mat matConvRes(nConvResH, nConvResW, CV_32FC1);29     memcpy(matConvRes.data, pConvRes, sizeof(float)* nConvResH * nConvResW);30 31     ippsFree(pBuffer);32     delete[] pConvRes;33     pConvRes = nullptr;34 35     return matConvRes;36 }

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

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

 

转载于:https://www.cnblogs.com/darkknightzh/p/5462631.html

你可能感兴趣的文章
计算机网络基础知识
查看>>
C#里如何遍历枚举所有的项
查看>>
如何在键盘出现时滚动表格,以适应输入框的显示
查看>>
超级强大的鼠标手势工具
查看>>
常用Dockerfile举例
查看>>
jquery的ajax用法
查看>>
设计模式-策略模式(Strategy)
查看>>
django orm 数据查询详解
查看>>
JarvisOJ Basic 熟悉的声音
查看>>
C# list导出Excel(二)
查看>>
CAS 单点登录模块学习
查看>>
跟着辛星用PHP的反射机制来实现插件
查看>>
Android应用开发-网络编程①
查看>>
input中的name,value以及label中的for
查看>>
静态库制作-混编(工程是oc为基础)
查看>>
jQuery 显示加载更多
查看>>
代理模式
查看>>
Confluence 6 系统运行信息中的 JVM 内存使用情况
查看>>
Confluence 6 升级以后
查看>>
用JS实现版面拖拽效果
查看>>