示例
总览
本章节为您介绍HPL模块的各个示例功能、实现流程及实现细节,帮助您快速了解HPL模块的使用方法,示例介绍均以板端运行为例。示例的编译及运行请参考 快速上手 章节。
示例列表,默认使用dsp backend。
傅里叶变换示例
傅里叶变换示例执行脚本位于 ucp_tutorial/hpl/hpl_samples/script/01_fft_ifft_transform 目录下,
该示例展示了如何使用傅里叶变换、逆变换接口对图片进行滤波处理,信息在采集、传输或处理过程中可能会受到各种噪声的干扰,对某些类型的噪声来说,在频域上处理是更为有效和便捷的方式,此时就可以通过傅里叶变换的相关接口,在频域上去除这些噪声,再将滤波后的数据恢复到时域,达到去噪的目的,详细的实现方法请结合示例源码对比实践。
此示例中,直接执行示例脚本即可启动示例的处理流程:读取带噪声的正弦波、fft变换、频域滤波、ifft变换、保存去噪数据。
执行方法如下:
sh run_fft_ifft_tranform.sh
此外还可以通过追加 -help 命令获取示例用法介绍。
算子执行后会在 hpl_samples/data 目录下保存数据处理结果,本示例的生成物内容如下:
hpl_samples
└── data // 数据目录
├── fft1d_input_f32.txt // fft输入的带噪声数据
├── fft1d_output_f32.txt // fft输出的带噪声数据
├── ifft1d_output_f32.txt // ifft输出的去噪声数据
├── input_image_2d.jpg // fft2d的输入数据图像
├── input_image_f32.jpg // fft输入的带噪声数据图像
└── output_image_f32.jpg // ifft输出的去噪声数据图像
1D FFT示例的执行流程如下图:

如示例的执行流程图所示,该示例对数据的处理过程可以大致分为以下四个阶段:
-
生成正弦波数据,并添加噪声。将生成的数据以浮点类型保存在文件中,并在后续的运行中直接读取该数据。
-
对生成的数据进行傅里叶变换。
-
构造一个频域滤波器,对变换后的数据进行滤波。
-
将滤波结果进行傅里叶逆变换,还原正弦波数据。
构造噪声数据
这个环节构造了初始的输入数据,将正弦波作为原始数据,加噪后成为输入数据,并在后续的处理中去除噪声。噪声数据为频率为5HZ的正弦波叠加上高斯噪声,噪声构造代码如下:
for (int i = 0; i < data_length; ++i) {
double t = i / sample_rate;
signal.at<float>(i) = sin(2 * CV_PI * frequency * t);
if (i % 3 == 0) {
noise.at<float>(i) = rng.gaussian(0.2);
} else {
noise.at<float>(i) = 0.0f;
}
}
cv::Mat noisy_signal = signal + noise;
其中,正弦波原图像为:
添加噪声后的图像为:
傅里叶变换
傅里叶变换将数据由时域转变为频域,使得我们可以采用一些频域上的方法来处理数据。HPL模块提供了1维的快速傅里叶变换接口,请参考 Fast Fourier Transform 部分的介绍。具体代码如下:
int32_t ret{HB_UCP_SUCCESS};
hbFFTParam param_fft{point_size, 0};
ret = hbFFT1D(nullptr, &dst, &src, ¶m_fft);
FFT_LOGE_AND_RETURN_IF(ret != 0, HB_UCP_INVALID_ARGUMENT,
"hbFFT1D failed, error code: {}", ret);
其中dst为频域的输出数据,src为时域的输入数据,即噪声数据。
频域滤波
这一步骤是在频域上对数据进行处理,达到噪声滤波的效果。此处构造了一个滤波器,并将该滤波器与频域数据进行卷积,
具体实现如下:
int32_t complex_filter(hbHPLImaginaryData &imaginary) {
int32_t ret{HB_UCP_SUCCESS};
/**===============================================================
* copy imaginary data to mat
* ===============================================================*/
cv::Mat complex_data(1, imaginary.dimensionSize[0], CV_32FC2);
copy_imaginary_to_mat_32FC2<float32_t>(complex_data, imaginary);
/**===============================================================
* create filter and apply
* ===============================================================*/
int32_t data_length = imaginary.dimensionSize[0];
cv::Mat filter = cv::Mat::zeros(complex_data.size(), CV_32F);
create_band_pass_filter(filter, 0, data_length / 220, data_length,
data_length);
cv::Mat filter_complex[] = {filter, cv::Mat::zeros(filter.size(), CV_32F)};
cv::Mat complex_filter, filtered_data;
merge(filter_complex, 2, complex_filter);
mulSpectrums(complex_data, complex_filter, filtered_data, 0, true);
/**===============================================================
* copy mat to imaginary data
* ===============================================================*/
copy_mat_32FC2_to_imaginary<float32_t>(imaginary, filtered_data);
return ret;
}
代码中将虚数结构体数据转换为了cv::Mat的数据类型,通过opencv提供的相关接口创建并应用了频域滤波器,最后将滤波结果转换为虚数结构体。
傅里叶逆变换
傅里叶逆变换将数据由频域转变为时域,使得数据的展现、存储方式更符合平时的认知。HPL模块提供了1维的快速傅里叶逆变换接口,请参考 Inverse Fast Fourier Transform 部分的介绍。具体代码如下:
int32_t ret{HB_UCP_SUCCESS};
hbIFFTParam param_ifft{point_size, 0};
ret = hbIFFT1D(nullptr, &dst, &src, ¶m_ifft);
FFT_LOGE_AND_RETURN_IF(ret != 0, HB_UCP_INVALID_ARGUMENT,
"hbIFFT1D failed, error code: {}", ret);
其中dst为时域的输出数据,src为频域的输入数据。
消除噪声后的图像为:
