IPP的资料网上比较少,主要还是参考Inter官网和文档
官方文档ipps.pdf主要是对数据做处理,包括加减乘除、FFT、DFT等
文档ippi.pdf只要是对图像做处理,包括通道转换、图片处理等
IPP最新的几个版本删掉了生成图片的函数,所以使用IPP加速计算,然后再用opencv生成本地图片
1、搭建VS+IPP+Opencv环境(前一篇文章)
2、IPP的数据Ipp32f 转换成 Opencv的Mat数据
#define READ_BYTES 32768 #define RC 8192 Ipp32f *specturmData = ippsMalloc_32f(READ_BYTES);//创建Ipp32f //添加给specturmData 赋值之类的操作 //........ //........ int num=0; Mat mat; mat.create(READ_BYTES, RC, CV_32F);//创建mat数组,设定数组高度为32768,长度为8192,也就是画出一幅图32768*8192 while(num<RC)//把specturmData 赋给mat { for (int i = 0; i < READ_BYTES ; i++) { mat.at<float>(i, num) = specturmData[i];//逐个赋值 if (specturmData[i] > max) max = specturmData[i]; if (specturmData[i] < min) min = specturmData[i]; } num++; }
3、将mat存成本地图片
//添加对mat的数据处理 //...... //...... imwrite("my.bmp", mat);//画图
4、用IPP 做FFT变换
新版的IPP删除了ippsFFTInitAlloc_R_32f等函数,如图文档附录给出了替代方案
int CalculateSpectrumByReal(short* rData, int samplePoint, float* specturmData, int &outSpecturmDataLength, int winOpt, int fftOrder)/*计算频谱*/ { IppStatus status; int segement, fftPoint; IppsFFTSpec_R_32f* spec; fftPoint = (int)pow(2.0, fftOrder); //FFT 点数 outSpecturmDataLength = fftPoint / 2; //输出数据长度 = FFT点数的一半 Ipp32f *fData = ippsMalloc_32f(samplePoint);//设置浮点数组 fData Ipp32f *x = ippsMalloc_32f(fftPoint);//设置浮点数组 x Ipp32f *X = ippsMalloc_32f(fftPoint + 2);//设置浮点数组 X Ipp32f *mag = ippsMalloc_32f(outSpecturmDataLength);//求abs()后的幅度数据 一半的下标 memset(fData, 0, sizeof(Ipp32f)*samplePoint); //初始化 memset(x, 0, sizeof(Ipp32f)*fftPoint);//初始化 memset(X, 0, sizeof(Ipp32f)*(fftPoint + 2));//初始化 memset(mag, 0, sizeof(Ipp32f)*outSpecturmDataLength);//初始化 memset(specturmData, 0, sizeof(Ipp32f)*outSpecturmDataLength);//初始化 ippsConvert_16s32f(rData, fData, samplePoint);//转ipp结构 int sizeSpec = 0; int sizeInit = 0; int sizeBuffer = 0;
/*替代已经去掉的ippsFFTInitAlloc_R_32f函数*/ status = ippsFFTGetSize_R_32f(fftOrder, IPP_FFT_DIV_INV_BY_N, ippAlgHintAccurate, &sizeSpec, &sizeInit, &sizeBuffer); Ipp8u *pMemSpec = ippsMalloc_8u(sizeSpec); Ipp8u *pMemInit = ippsMalloc_8u(sizeInit); Ipp8u *pMemBuffer = ippsMalloc_8u(sizeBuffer); status = ippsFFTInit_R_32f(&spec, fftOrder, IPP_FFT_DIV_FWD_BY_N, ippAlgHintAccurate, pMemSpec, pMemInit); segement = (int)(samplePoint / fftPoint); //做FFT时的分段数 参数设定 for (int i = 0; i<segement; i++) { memcpy(x, fData + i*fftPoint, fftPoint * sizeof(Ipp32f)); status = ippsFFTFwd_RToCCS_32f(x, X, spec, pMemBuffer); //do fft... ippsMagnitude_32fc((Ipp32fc*)X, mag, outSpecturmDataLength); //abs()... ippsAdd_32f_I(mag, specturmData, outSpecturmDataLength); } ippsDivC_32f_I(segement, specturmData, outSpecturmDataLength);//求平均 ippsLn_32f_I(specturmData, outSpecturmDataLength); //求Ln,因为IPP函数不支持浮点的10Log10计算这里通过Ln进行转换计算 ippsDivC_32f_I(2.3026, specturmData, outSpecturmDataLength);// log(e,10)=2.3026 ippsMulC_32f_I(20.0, specturmData, outSpecturmDataLength); //20log10() ippsFree(spec); ippsFree(fData); ippsFree(x); ippsFree(X); ippsFree(mag); return status; }