Qwt库画Spectrogram声谱图

一.Qwt库

1.Qwt库功能说明

Qwt是一个用于数据可视化的开源软件库,它提供了丰富的图表绘制功能,使得开发者可以轻松地创建各种类型的图表,如曲线图、散点图、柱状图等。Qwt库基于Qt框架开发,可以与Qt应用程序无缝集成,为用户提供了强大的数据可视化能力。

Qwt是一个强大的数据可视化工具,提供了丰富的图表绘制功能和交互功能,以及灵活的扩展性。它可以帮助开发者快速、高效地实现数据可视化需求,提高数据分析和决策的效果。无论是在科学研究、工程设计还是商业分析等领域,Qwt都能发挥重要的作用,为用户提供优秀的数据可视化体验。

2.下载

qwt - snapshot.debian.org

3.官方文档

https://qwt.sourceforge.io/class_qwt_plot_spectrogram.html

二.Qwt库应用

  1. 可以画曲线图、散点图、柱状图等,这些功能QCustomPlot、QChart均可以实现,但Qwt库还可以画Spectrogram频谱图,应用在科学研究、工程设计还是商业分析等领域。
  2. Spectrogram频谱图介绍

频谱图(Spectrogram)是一种用于表示信号频率特性的图形表示,广泛应用于信号处理、音频处理、语音识别等领域。

频谱图通过将信号分解成不同频率的成分,并计算每个成分的幅度和相位信息,从而将信号的频率特性以可视化的方式呈现出来。在频谱图中,横轴表示时间,纵轴表示频率,颜色或灰度表示该频率分量的幅度或相位。

频谱图可以分为线性频谱图和对数频谱图两种类型。线性频谱图将幅度信息线性映射到颜色或灰度上,通常用于表示信号的细节和动态范围。对数频谱图则将幅度信息对数映射到颜色或灰度上,可以更好地突出不同频率分量的相对大小,尤其是在信号中有较大动态范围的情况下。

频谱图可以通过各种算法和工具来生成,例如快速傅里叶变换(FFT)、短时傅里叶变换(STFT)等。在MATLAB等数学软件中,也有专门的函数来生成频谱图。

频谱图在许多领域中都有广泛的应用,例如:

(1).音频处理:频谱图常用于音频信号处理中,如音频分析、音乐信息检索、语音识别等。通过对音频信号进行频谱分析,可以提取出音频的音高、音色、音量等特征信息。

(2).故障诊断:在机械故障诊断中,通过对机器产生的声音或振动信号进行频谱分析,可以识别出异常频率成分,从而判断故障的类型和位置。

(3).通信系统:在通信系统中,频谱图可以用于信号的调制、解调、干扰抑制等方面。通过对信号的频谱进行分析和处理,可以提高通信系统的性能和可靠性。

(4).生物医学工程:在生物医学工程领域,频谱图可以用于心电图(ECG)、脑电图(EEG)等生理信号的分析和处理,帮助医生更好地诊断疾病和监测病人的生理状态。

(5).雷达和声呐:在雷达和声呐领域,频谱图可以用于目标检测、信号处理等方面。通过对接收到的信号进行频谱分析,可以提取出目标的信息和特征。

(6).总之,频谱图作为一种可视化工具,在信号处理、音频处理、通信、生物医学工程等领域中都有着广泛的应用。通过频谱图,人们可以更好地理解信号的频率特性和动态变化情况,从而为各种应用提供重要的支持和参考。

3.Qwt库Spectrogram频谱图代码实现

(1)矩阵数据输入方式

#include "Plot.h"

#include "qwt_color_map.h"

#include "qwt_plot_spectrogram.h"

#include "qwt_scale_widget.h"

#include "qwt_scale_draw.h"

#include "qwt_plot_zoomer.h"

#include "qwt_plot_panner.h"

#include "qwt_plot_layout.h"

#include "qwt_plot_renderer.h"

#include "qwt_interval.h"

#include "qwt_painter.h"

#include "qwt_plot_canvas.h"

#include "qwt_plot_magnifier.h"

#include

#include

#include

#include

#include

#include

namespace

{

    class RasterData : public QwtMatrixRasterData

    {

      public:

        RasterData()

        {

            const double matrix[] =

            {

                1, 2, 4, 1,

                6, 3, 5, 2,

                4, 2, 1, 5,

                5, 4, 2, 3

            };

            QVector< double > values;

            for ( uint i = 0; i < sizeof( matrix ) / sizeof( double ); i++ )

            {

                values += matrix[i];

                qDebug()<

            }

            const int numColumns = 4;

            setValueMatrix( values, numColumns );

            setInterval( Qt::XAxis,

                QwtInterval( -0.5, 13.5, QwtInterval::ExcludeMaximum ) );

            setInterval( Qt::YAxis,

                QwtInterval( -0.5, 14.5, QwtInterval::ExcludeMaximum ) );

            setInterval( Qt::ZAxis, QwtInterval( 1.0, 6.0 ) );

        }

    };

    class ColorMap : public QwtLinearColorMap

    {

      public:

        ColorMap()

            : QwtLinearColorMap( Qt::darkBlue, Qt::darkRed )

        {

            addColorStop( 0.2, Qt::blue );

            addColorStop( 0.4, Qt::cyan );

            addColorStop( 0.6, Qt::yellow );

            addColorStop( 0.8, Qt::red );

        }

    };

}

Plot::Plot( QWidget* parent ):

    QwtPlot( parent )

{

    QwtPlotCanvas* canvas = new QwtPlotCanvas();

    canvas->setBorderRadius( 10 );

    setCanvas( canvas );

#if 0

    QwtPlotGrid* grid = new QwtPlotGrid();

    grid->setPen( Qt::DotLine );

    grid->attach( this );

#endif

    m_spectrogram = new QwtPlotSpectrogram();

    m_spectrogram->setRenderThreadCount( 0 ); // use system specific thread count

    m_spectrogram->setColorMap( new ColorMap() );

    m_spectrogram->setData( new RasterData() );

    m_spectrogram->attach( this );

    const QwtInterval zInterval = m_spectrogram->data()->interval( Qt::ZAxis );

    // A color bar on the right axis

    QwtScaleWidget* rightAxis = axisWidget( QwtAxis::YRight );

    rightAxis->setColorBarEnabled( true );

    rightAxis->setColorBarWidth( 40 );

    rightAxis->setColorMap( zInterval, new ColorMap() );

    setAxisScale( QwtAxis::YRight, zInterval.minValue(), zInterval.maxValue() );

    setAxisVisible( QwtAxis::YRight );

    plotLayout()->setAlignCanvasToScales( true );

    setAxisScale( QwtAxis::XBottom, 0.0, 13.0 );

    setAxisMaxMinor( QwtAxis::XBottom, 0 );

    setAxisScale( QwtAxis::YLeft, 0.0, 13.0 );

    setAxisMaxMinor( QwtAxis::YLeft, 0 );

    QwtPlotMagnifier* magnifier = new QwtPlotMagnifier( canvas );

    magnifier->setAxisEnabled( QwtAxis::YRight, false );

    QwtPlotPanner* panner = new QwtPlotPanner( canvas );

    panner->setAxisEnabled( QwtAxis::YRight, false );

}

void Plot::exportPlot()

{

    QwtPlotRenderer renderer;

    renderer.exportTo( this, "rasterview.pdf" );

}

void Plot::setResampleMode( int mode )

{

    RasterData* rasterData = static_cast< RasterData* >( m_spectrogram->data() );

    rasterData->setResampleMode(

        static_cast< QwtMatrixRasterData::ResampleMode >( mode ) );

    replot();

}

(2).模拟生成数据方式

#include "Plot.h"

#include "qwt_color_map.h"

#include "qwt_plot_spectrogram.h"

#include "qwt_scale_widget.h"

#include "qwt_scale_draw.h""

#include "qwt_plot_zoomer.h""

#include "qwt_plot_panner.h""

#include "qwt_plot_layout.h""

#include "qwt_plot_renderer.h""

#include "qwt_interval.h""

#include "qwt_painter.h""

#include

#include

#include

#include

namespace

{

    class MyZoomer : public QwtPlotZoomer

    {

      public:

        MyZoomer( QWidget* canvas )

            : QwtPlotZoomer( canvas )

        {

            setTrackerMode( AlwaysOn );

        }

        virtual QwtText trackerTextF( const QPointF& pos ) const QWT_OVERRIDE

        {

            QColor bg( Qt::white );

            bg.setAlpha( 200 );

            QwtText text = QwtPlotZoomer::trackerTextF( pos );

            text.setBackgroundBrush( QBrush( bg ) );

            return text;

        }

    };

    class SpectrogramData : public QwtRasterData

    {

      public:

        SpectrogramData()

        {

            // some minor performance improvements when the spectrogram item

            // does not need to check for NaN values

            setAttribute( QwtRasterData::WithoutGaps, true );

            m_intervals[ Qt::XAxis ] = QwtInterval( -1.5, 1.5 );

            m_intervals[ Qt::YAxis ] = QwtInterval( -1.5, 1.5 );

            m_intervals[ Qt::ZAxis ] = QwtInterval( 0.0, 10.0 );

        }

        virtual QwtInterval interval( Qt::Axis axis ) const QWT_OVERRIDE

        {

            if ( axis >= 0 && axis <= 2 )

                return m_intervals[ axis ];

            return QwtInterval();

        }

        virtual double value( double x, double y ) const QWT_OVERRIDE

        {

            const double c = 0.842;

            //const double c = 0.33;

            const double v1 = x * x + ( y - c ) * ( y + c );

            const double v2 = x * ( y + c ) + x * ( y + c );

            return 1.0 / ( v1 * v1 + v2 * v2 );

        }

      private:

        QwtInterval m_intervals[3];

    };

    class LinearColorMap : public QwtLinearColorMap

    {

      public:

        LinearColorMap( int formatType )

            : QwtLinearColorMap( Qt::darkCyan, Qt::red )

        {

            setFormat( ( QwtColorMap::Format ) formatType );

            addColorStop( 0.1, Qt::cyan );

            addColorStop( 0.6, Qt::green );

            addColorStop( 0.95, Qt::yellow );

        }

    };

    class HueColorMap : public QwtHueColorMap

    {

      public:

        HueColorMap( int formatType )

            : QwtHueColorMap( QwtColorMap::Indexed )

        {

            setFormat( ( QwtColorMap::Format ) formatType );

            //setHueInterval( 240, 60 );

            //setHueInterval( 240, 420 );

            setHueInterval( 0, 359 );

            setSaturation( 150 );

            setValue( 200 );

        }

    };

    class SaturationColorMap : public QwtSaturationValueColorMap

    {

      public:

        SaturationColorMap( int formatType )

        {

            setFormat( ( QwtColorMap::Format ) formatType );

            setHue( 220 );

            setSaturationInterval( 0, 255 );

            setValueInterval( 255, 255 );

        }

    };

    class ValueColorMap : public QwtSaturationValueColorMap

    {

      public:

        ValueColorMap( int formatType )

        {

            setFormat( ( QwtColorMap::Format ) formatType );

            setHue( 220 );

            setSaturationInterval( 255, 255 );

            setValueInterval( 70, 255 );

        }

    };

    class SVColorMap : public QwtSaturationValueColorMap

    {

      public:

        SVColorMap( int formatType )

        {

            setFormat( ( QwtColorMap::Format ) formatType );

            setHue( 220 );

            setSaturationInterval( 100, 255 );

            setValueInterval( 70, 255 );

        }

    };

    class AlphaColorMap : public QwtAlphaColorMap

    {

      public:

        AlphaColorMap( int formatType )

        {

            setFormat( ( QwtColorMap::Format ) formatType );

            //setColor( QColor("DarkSalmon") );

            setColor( QColor("SteelBlue") );

        }

    };

    class Spectrogram : public QwtPlotSpectrogram

    {

      public:

        int elapsed() const

        {

            return m_elapsed;

        }

        QSize renderedSize() const

        {

            return m_renderedSize;

        }

      protected:

        virtual QImage renderImage(

            const QwtScaleMap& xMap, const QwtScaleMap& yMap,

            const QRectF& area, const QSize& imageSize ) const QWT_OVERRIDE

        {

            QElapsedTimer t;

            t.start();

            QImage image = QwtPlotSpectrogram::renderImage(

                xMap, yMap, area, imageSize );

            m_elapsed = t.elapsed();

            m_renderedSize = imageSize;

            return image;

        }

      private:

        mutable int m_elapsed;

        mutable QSize m_renderedSize;

    };

}

Plot::Plot( QWidget* parent )

    : QwtPlot( parent )

    , m_alpha(255)

{

    m_spectrogram = new Spectrogram();

    m_spectrogram->setRenderThreadCount( 0 ); // use system specific thread count

    m_spectrogram->setCachePolicy( QwtPlotRasterItem::PaintCache );

    QList< double > contourLevels;

    for ( double level = 0.5; level < 10.0; level += 1.0 )

        contourLevels += level;

    m_spectrogram->setContourLevels( contourLevels );

    m_spectrogram->setData( new SpectrogramData() );

    m_spectrogram->attach( this );

    const QwtInterval zInterval = m_spectrogram->data()->interval( Qt::ZAxis );

    // A color bar on the right axis

    QwtScaleWidget* rightAxis = axisWidget( QwtAxis::YRight );

    rightAxis->setTitle( "Intensity" );

    rightAxis->setColorBarEnabled( true );

    setAxisScale( QwtAxis::YRight, zInterval.minValue(), zInterval.maxValue() );

    setAxisVisible( QwtAxis::YRight );

    plotLayout()->setAlignCanvasToScales( true );

    setColorMap( Plot::RGBMap );

    // LeftButton for the zooming

    // MidButton for the panning

    // RightButton: zoom out by 1

    // Ctrl+RighButton: zoom out to full size

    QwtPlotZoomer* zoomer = new MyZoomer( canvas() );

    zoomer->setMousePattern( QwtEventPattern::MouseSelect2,

        Qt::RightButton, Qt::ControlModifier );

    zoomer->setMousePattern( QwtEventPattern::MouseSelect3,

        Qt::RightButton );

    QwtPlotPanner* panner = new QwtPlotPanner( canvas() );

    panner->setAxisEnabled( QwtAxis::YRight, false );

    panner->setMouseButton( Qt::MiddleButton );

    // Avoid jumping when labels with more/less digits

    // appear/disappear when scrolling vertically

    const int extent = QwtPainter::horizontalAdvance(

        axisWidget( QwtAxis::YLeft )->fontMetrics(), "100.00" );

    axisScaleDraw( QwtAxis::YLeft )->setMinimumExtent( extent );

    const QColor c( Qt::darkBlue );

    zoomer->setRubberBandPen( c );

    zoomer->setTrackerPen( c );

}

void Plot::showContour( bool on )

{

    m_spectrogram->setDisplayMode( QwtPlotSpectrogram::ContourMode, on );

    replot();

}

void Plot::showSpectrogram( bool on )

{

    m_spectrogram->setDisplayMode( QwtPlotSpectrogram::ImageMode, on );

    m_spectrogram->setDefaultContourPen(

        on ? QPen( Qt::black, 0 ) : QPen( Qt::NoPen ) );

    replot();

}

void Plot::setColorTableSize( int type )

{

    int numColors = 0;

    switch( type )

    {

        case 1:

            numColors = 256;

            break;

        case 2:

            numColors = 1024;

            break;

        case 3:

            numColors = 16384;

            break;

    }

    m_spectrogram->setColorTableSize( numColors );

    replot();

}

void Plot::setColorMap( int type )

{

    QwtScaleWidget* axis = axisWidget( QwtAxis::YRight );

    const QwtInterval zInterval = m_spectrogram->data()->interval( Qt::ZAxis );

    m_mapType = type;

    const QwtColorMap::Format format = QwtColorMap::RGB;

    int alpha = m_alpha;

    switch( type )

    {

        case Plot::HueMap:

        {

            m_spectrogram->setColorMap( new HueColorMap( format ) );

            axis->setColorMap( zInterval, new HueColorMap( format ) );

            break;

        }

        case Plot::SaturationMap:

        {

            m_spectrogram->setColorMap( new SaturationColorMap( format ) );

            axis->setColorMap( zInterval, new SaturationColorMap( format ) );

            break;

        }

        case Plot::ValueMap:

        {

            m_spectrogram->setColorMap( new ValueColorMap( format ) );

            axis->setColorMap( zInterval, new ValueColorMap( format ) );

            break;

        }

        case Plot::SVMap:

        {

            m_spectrogram->setColorMap( new SVColorMap( format ) );

            axis->setColorMap( zInterval, new SVColorMap( format ) );

            break;

        }

        case Plot::AlphaMap:

        {

            alpha = 255;

            m_spectrogram->setColorMap( new AlphaColorMap( format ) );

            axis->setColorMap( zInterval, new AlphaColorMap( format ) );

            break;

        }

        case Plot::RGBMap:

        default:

        {

            m_spectrogram->setColorMap( new LinearColorMap( format ) );

            axis->setColorMap( zInterval, new LinearColorMap( format ) );

        }

    }

    m_spectrogram->setAlpha( alpha );

    replot();

}

void Plot::setAlpha( int alpha )

{

    // setting an alpha value doesn't make sense in combination

    // with a color map interpolating the alpha value

    m_alpha = alpha;

    if ( m_mapType != Plot::AlphaMap )

    {

        m_spectrogram->setAlpha( alpha );

        replot();

    }

}

void Plot::drawItems( QPainter* painter, const QRectF& canvasRect,

    const QwtScaleMap maps[QwtAxis::AxisPositions] ) const

{

    QwtPlot::drawItems( painter, canvasRect, maps );

    if ( m_spectrogram )

    {

        Spectrogram* spectrogram = static_cast< Spectrogram* >( m_spectrogram );

        QString info( "%1 x %2 pixels: %3 ms" );

        info = info.arg( spectrogram->renderedSize().width() );

        info = info.arg( spectrogram->renderedSize().height() );

        info = info.arg( spectrogram->elapsed() );

        Plot* plot = const_cast< Plot* >( this );

        plot->Q_EMIT rendered( info );

    }

}

#ifndef QT_NO_PRINTER

void Plot::printPlot()

{

    QPrinter printer( QPrinter::HighResolution );

#if QT_VERSION >= 0x050300

    printer.setPageOrientation( QPageLayout::Landscape );

#else

    printer.setOrientation( QPrinter::Landscape );

#endif

    printer.setOutputFileName( "spectrogram.pdf" );

    QPrintDialog dialog( &printer );

    if ( dialog.exec() )

    {

        QwtPlotRenderer renderer;

        if ( printer.colorMode() == QPrinter::GrayScale )

        {

            renderer.setDiscardFlag( QwtPlotRenderer::DiscardBackground );

            renderer.setDiscardFlag( QwtPlotRenderer::DiscardCanvasBackground );

            renderer.setDiscardFlag( QwtPlotRenderer::DiscardCanvasFrame );

            renderer.setLayoutFlag( QwtPlotRenderer::FrameWithScales );

        }

        renderer.renderTo( this, printer );

    }

}

Qwt库画Spectrogram声谱图_第1张图片

可以再本博客的资源中直接下载工程代码。

你可能感兴趣的:(QT系列,物联网,qt,开发语言)