PDA

View Full Version : General question Spectrogram plot



QTim
16th December 2013, 16:09
Hallo everybody,

I would like to use a spectrogram plot in my application. It is a bigger software-project and due to this I have some "boudary conditions" in the project design which I cannot change.

For example:
-The input matrix is a double values matrix and has a maximal size of 192000x140 values.
-As a minimum the application should show every half second an updated version of the spectrogram. (so faster is better...)

I want to use bilinear interpolation.

So the question is:
What would be the optimal approach for an implementation?
-->Should I copy the values in a QVectror like in the "rasterview"-example or should i use the values()-function like in the "spectrogram"-example?

What would be the fastest option? Or is it impossible to show such big images with such a high update-rate?


Thank you very much!!
QTim

Uwe
17th December 2013, 07:21
Or is it impossible to show such big images with such a high update-rate
The size of the rendered image depends on size/resolution of the plot canvas.

The size of your input matrix is irrelevant, only its resolution might have an effect, when it is below the screen resolution and it is possible to render the image in lower resolution ( scaling it when painting later ).
In your case this will be the case in vertical direction or horizontally, when you zoom in deep.


I want to use bilinear interpolation.
The type of resampling has a significant effect on the performance - so be careful here. F.e. for your use case it looks like a vertical interpolation makes sense, while interpolating horizontally seems to be more or less pointless - at least as long as you don't zoom in deep. So it should be possible to implement something faster than bilinear interpolation - f.e. interpolating vertically only.

What would be the fastest option?
As the performance doesn't depend on your matrix ( and its size ) you can check easily in a small test program, what type of resampling is possible for a certain refresh rate on your target system. When it is a multicore CPU you should always enable mutithreading ( QwtPlotItem::setRenderThreadCount() ). As different tiles of an image can be rendered in parallel easily you will see an almost linear effect on the performance.



What would be the optimal approach for an implementation?
-->Should I copy the values in a QVectror like in the "rasterview"-example or should i use the values()-function like in the "spectrogram"-example?
I wouldn't use QwtMatrixRasterData if it means, that you have to copy your samples. Beside a waste of memory, this would be an operation, that depends on the size of your matrix and might be more performance bottleneck than rendering the image itself.

When implementing YourRasterData::value() you can have a look at the implementation of QwtMatrixRasterData::value(), what might help for your one dimensional interpolation. But always be aware, that YourRasterData::value() is called ( for each pixel of the rendered image ! ) very often and needs to be implemented as fast as possible: everything what can be calculated outside the render loop ( f.e. in YourRasterData::initRaster() ) should be done there.

Uwe

QTim
17th December 2013, 08:33
Thank you, Uwe!

I will try this.

QTim

QTim
19th December 2013, 18:18
you can have a look at the implementation of QwtMatrixRasterData::value(), what might help for your one dimensional interpolation.


Sorry, Uwe. I don't know exactly what you mean. Do you mean, I can have a look at QwtMatrixRasterData::value() to see, how the linear interpolation is done? But if i have a look there, it is just a virtual function. And it's empty. Can you precice your advice a little bit for me?

Thank you!

QTim

Uwe
20th December 2013, 07:30
Do you mean, I can have a look at QwtMatrixRasterData::value() to see, how the interpolation is done?
Yes.

But if i have a look there, it is just a virtual function. And it's empty.
No it isn't: QwtMatrixRasterData::value() != QwtRasterData::value().

Uwe

QTim
6th January 2014, 18:36
Hi Uwe,

it would be cool, if you could help me again with two questions:

1.
I have implemented the spectrogram plot, just like you did. But now, the plot area does not fit completly. There is some space between the borders of the plot and the beginnig of the spectrogram. I have no clue how to fix it. Please have a look in the screenshot (I marked it red):
9912

I set the interval:

setInterval( Qt::XAxis, QwtInterval( -0.5,192000+0.5, QwtInterval::ExcludeMaximum ) );
setInterval( Qt::YAxis, QwtInterval( -10, 10, QwtInterval::ExcludeMaximum ) );

and scaled the axis:


setAxisScale( QwtPlot::xBottom,0,192000 );
setAxisMaxMinor( QwtPlot::xBottom, 1 );
setAxisScale( QwtPlot::yLeft, -9.5,9.5 );
setAxisMaxMinor( QwtPlot::yLeft, 1 );

What is wrong there? :confused:


2.
The values on the axes should be different. f.e. the values on the y-axis represent angles with more than one angle between each other. So the vaues in the data matrix represent valuese at the 2nd, 4th, 6th angle. To clear this up: if you have a look in the screenshot again -there is only one value written on the y-axis- but however, this i want this to be a 10, not a 5... How can I change it?

Thank you very much!!

QTim

Uwe
6th January 2014, 19:42
What is wrong there? :confused:
Probably nothing: the tick labels need some extra space ( or the canvas margin ), so that there is an margin between the ticks and the border of the canvas, where you don't have values.
To avoid this effect you can add the following line to your code:


plot->plotLayout()->setAlignCanvasToScales( true );



The values on the axes should be different. f.e. the values on the y-axis represent angles with more than one angle between each other. So the vaues in the data matrix represent valuese at the 2nd, 4th, 6th angle. To clear this up: if you have a look in the screenshot again -there is only one value written on the y-axis- but however, this i want this to be a 10, not a 5... How can I change it?

Have a look at the various QwtPlot::setAxisXY() methods.

Uwe