一文玩转QT编程之FFTW

5 篇文章 0 订阅
1 篇文章 0 订阅

上一篇《(项目实战)基于QT嵌入式ARM数据采集上位机设计

一 、 引言

笔者在Linux环境下,将qt的软件部署到arm中,在使用fftw时出现找不到lib库的错误,折腾许久,终于得以解决,记录下来留给有需要的朋友。

开发环境说明:

  1. Linux环境下,将qt编写的软件部署到arm中
  2. 笔者使用的是Ubuntu16.04,编译器是 arm-linux-gnueabihf-gcc
二 、 FFTW 简介
1. FFTW是什么?

FFTW(The Fastest Fourier Transform in the West)是一个计算一维或者多维DFT(the discrete Fourier transform)的c程序子库,支持任意输入长度,可以是实数或者复数数据。

2. FFTW特点
  1. 比其他开源傅里叶变换速度快
  2. 支持一维和多维变换
  3. 支持任意输入长度变换
  4. 纯实数输入输出时能快速变换
  5. 支持实数奇偶输入数据变换
  6. 高效处理多个或者多步变换
  7. 并行变换,只对支持多线程的机器有效
  8. 对使用C编译器的平台都是可移植的
三 、 编译安装
1 编译安装
  1. 资源下载

    ftp://ftp.fftw.org/pub/fftw/fftw-3.3.10.tar.gz

    #解压并进入文件夹
    tar zxvf fftw-3.3.10.tar.gz
    cd fftw-3.3.10
    
  2. 配置
    在fftw-3.3.10文件夹打开终端

    ./configure --prefix=/usr/local/fftw --host=arm-linux --disable-fortran --enable-shared=yes --with-slow-timer CC=arm-linux-gnueabihf-gcc
    

参数使用说明:

--prefix=/usr/local/fftw  #配置安装目录
--host=arm-linux     #宿主机类型
--enable-shared=yes  #编译共享库
CC=arm-linux-gnueabihf-gcc #设置编译
#说明 :其他没有配置说明时选择默认配置,如果有需要,可使用 ./configure -help 查看配置选项,如配置浮点型精度以及双浮点型精度,具体请查看具体参数
   sudo make
   sudo make install
  1. 经过以上步骤,编译完成,在/usr/local/fftw中会找到编译的库文件,我在做项目时,习惯将库文件拷到工程文件中,即将/usr/local中的fftw文件夹全部复制过去,然后再fftw文件夹下创建fftw.pri,无论哪种方式按照你的习惯就好。
2. 测试是否安装成功
  1. qt下的配置,在工程文件下的fftw文件夹下创建fftw.pri,fftw.pri代码如下

    #fftw.pri
    # FFTW 安装路径
    FFTW_PATH = $$PWD
    
    # FFTW 插件相关库所在路径(例如:xx.lib)
    FFTW_LIB_PATH = $$FFTW_PATH/lib
    
    # FFTW 插件相关头文件所在路径(例如:xx.h)
    FFTW_INCLUDE_PATH = $$FFTW_PATH/include
    
    INCLUDEPATH += $$FFTW_INCLUDE_PATH
    
    LIBS += -L$$FFTW_LIB_PATH -lfftw3 
    

    注意:

    LIBS += -L$$FFTW_LIB_PATH -lfftw3 这里一定是这种写法,而不是像windows下的写法,笔者这里折腾很久,还是一次偶然发现

    #windows下的写法
    LIBS += -L$$FFTW_LIB_PATH/
                  -llibfftw3/
                  -llibfftw3f
                  #这种写法在Linux下找不到链接库
    

    *.pro中包含 fftw.pri,即

    include(fftw.pri)
    
  2. 如果不是创建 .pri的这种方式,可以在 .pro文件加入如下内容

    INCLUDEPATH += /usr/local/fftw/include
    
    LIBS += -L"/usr/local/fftw/lib" -lfftw3
    
  3. qt测试文件内容,只要编译器能够将以下代码编译通过,即fftw安装成功

    
    #include "widget.h"
    //#include "stdio.h"
    #include "fftw3.h"
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
    {
        int N = 150;
       fftw_complex *out_fft = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
    }
    
    Widget::~Widget()
    {
    }
    
3 如在arm开发板中进行使用,还需要如下配置:
  1. 将程序部署到arm中,还需将库文件放到arm的 /lib

    这里由于lib下.so文件多数是快捷方式,只需将那个不是快捷方式的.so文件复制到 arm下的/lib中,
    例 : 笔者fftw文件夹下 libfftw3.so.3.6.10不是快捷方式,我将其复制到arm中的 /lib中,qt编写的软件部署到arm中,会提示:缺少libfftw3.so.3,只需将libfftw3.so.3.6.10改名为 libfftw3.so.3即可,再次部署即可。

四 、FFTW使用实例

以下是我在csdn更新的项目实例中代码,大家可以参考一下。具体细节可以查看我的上几篇博客内容,
sllfft.cpp文件

#include "sllfft.h"
#include <QDebug>
sllFFT::sllFFT(qint16 len)
{
        nLen = len;
    fftInit(nLen);
}
void sllFFT::pushdata(QVector<double> valueVector)
{
    static QVector<double> fft_In;
    for (int i=0; i<valueVector.size(); i++) {
        fft_In.append(valueVector[i]);

        if(fft_In.size() >= nLen){
            fftunit(fft_In,nLen);
            emit processCompleted(this->xAxis, this->outvalue);
//            qDebug() << outvalue.size();
            fft_In.resize(0);
          // qDebug()<<""<<"t_vector"<<t_vector.size()<<time.elapsed()/1000.0<<"s";//测试时间ms级别
        }
    }
}
void sllFFT::fftInit(qint16 len)
{

    out_fft = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * len);

    xAxis.resize(len/2);
        for (quint16 i=0;i<len/2;i++)
        {
            xAxis[i] = i * (DATA_SAMPLING_FREQ/nLen);
        }
//        xAxis.remove(0, 2);
}
void sllFFT::fftunit(QVector<double> Value,qint16 len)
{
    QVector<double> psd_amp(len);
      for (quint16 i = 0;i < len;i ++)
      {
          psd_amp[i] = 0.5*(1-qCos(2*M_PI*i/(len-1)))*qSqrt(1.633);
          Value[i]=Value[i]*psd_amp[i];
      }
      plan_fft = fftw_plan_dft_r2c_1d(len, &Value[0], out_fft, FFTW_ESTIMATE);
      fftw_execute(plan_fft);// 执行变换

      QVector<double> psd_amptemp(len/2);

      for (quint16 i = 0;i < len/2;i ++)
      {
          psd_amptemp[i] = qSqrt(((out_fft[i][0]*out_fft[i][0]+out_fft[i][1]*out_fft[i][1]))
                  /(len*DATA_SAMPLING_FREQ/4));
      }
      fftw_destroy_plan(plan_fft);

      outvalue.resize(psd_amptemp.size());
//    qDebug() << xAxis.size() << outvalue.size();
      for (int i=0;i<outvalue.size();i++)
      {
          {
              outvalue[i] = psd_amptemp[i];
          }
      }
}

sllfft.h文件

#ifndef SLLFFT_H
#define SLLFFT_H

#include <QObject>
#include "fftw3.h"
#include <QtMath>
#include <QVector>
class sllFFT : public QObject
{
#define DATA_SAMPLING_FREQ 1000
    Q_OBJECT
public:
    explicit sllFFT(qint16 len);
    void pushdata(QVector<double> valueVector);
signals:
    void processCompleted(QVector<double> t_vectorX, QVector<double> t_vectorY);
private:
    qint16 nLen;
    QVector<QVector<double>> outvaluetemp;
    QVector<double> outvalue;
     QVector<double> xAxis;
    fftw_plan plan_fft;
    fftw_complex *out_fft;
    void fftInit(qint16 len);
    void fftunit(QVector<double> Value,qint16 len);
   char AddData(double value);

};
#endif // SLLFFT_H
  • 2
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值