What is the best way to plot a spectrogram with openGL - c++

I have written a code to calculate the spectrogram of a sine & cos signals, applied the Hann Window, calculated FFT, Calculated log magnitude of frequency coefficients.
I tested that it is all working by writing a simple function in openGL to plot a magnitude-frequency spectrum and I got the following results:
As you can see, there are 2 bars which indicates the sine * cos waves.
I have all the information I need to plot a spectrogram (frequencies,magnitude,time)
Now my question is how can I draw that? my first thought was to draw dots, so I'll use the time array for the interval time I need to draw the dots on the X axie, frequencies array to where to draw them on the Y axis, and the magnitude would be the color of the dot.
Maybe that's an inefficient idea because I saw that drawing dots is really inefficient in openGL so I don't know what's a better idea, I couldn't find any "simple" examples of openGL spectrogram online.

#HolyBlackCat comment is the answer
"Make an array of colors, fill it once, then give it to GL as a texture"

Related

How to plot spectrogram from an array or (vector,list etc) containing raw data?

I have been working to find temporal displacement between audio signals using a spectrogram. I have a short array containing data of a sound wave (pulses at specific frequencies). Now I want to plot spectrogram from that array. I have followed this steps (Spectrogram C++ library):
It would be fairly easy to put together your own spectrogram. The steps are:
window function (fairly trivial, e.g. Hanning)
FFT (FFTW would be a good choice but if licensing is an issue then go for Kiss FFT or
similar)
calculate log magnitude of frequency domain components(trivial: log(sqrt(re * re + im * im))
Now after performing these 3 steps, I am stuck at how to plot the spectrogram from this available data? Being naive in this field, I need some clear steps ahead to plot the spectrogram.
I know that a simple spectrogram has Frequency at Y-Axis, time at X-axis and magnitude as the color intensity.
But how do I get these three things to plot the spectrogram? (I want to observe and analyze data behind spectral peaks(what's the value on Y-axis and X-axis), the main purpose of plotting spectrogram).
Regards,
Khubaib

GPU-Computation (CUDA) tex2d/tex3d - How to deal with anisotropic pixel/voxel

I am quite new to cuda programming and i have a question about the texXD function. My goal is to implement a simple GPU-based ray tracer using the optimized CUDA functionality.
See CUDA texture API that is used by NVIDIA.
At my research I have to deal with images that have a different resolution for every dimension (like CT images, (x,y) have a different resolution as (z)). Resampling to an isotropic pixel/voxel size might bring up some problems (especially for medical diagnosis).
For example i have an image with size (100px x 50px) and a resolution of (2px/mm x 1px/mm). The ray enters the image at an arbitrary point and leaves is somewhere else. The ray is sampled in the direction form entrance to leaving point. At each sample point (pos.x,pos.y) the tex2D function carries out an (bicubicbilinear) interpolation taking the neighbour pixel values into account weighted by their distance from the sample point.
example image:
In both shapes the corner points are named the same way(x1,y1),.... The only difference is the physical space between the corner points. The interpolation point is (x,y). I computed an example using the formula for rectangular grids and yield a different results for both grids. But if I use the ratio of areas of the numbered rectangles I got a different result.
My Question: Will CUDA take care of the different resolutions of the dimensions or does CUDA see all pixel in the same distance (and therefore as a squared grid)?
The formula used by CUDA seems to be the one for a squared grid (google:CUDA Texture fetching).
Or can I resample the image to squared grid before using tex2D without a substantial information loss?
Any suggestions are recommended. If you need some more clarification, feel free to ask. I will specifiy my question.
I don't believe what (I think it is) you are trying to do can be achieved using textures. The sole filtering mode supported using textures is described here.
Some salient points:
Textures don't have resolution. The just have dimensions.
Textures data is implicitly uniformly spaced in all dimensions.
Texture interpolation is done in a reduced accuracy fixed point arithmetic format which gives 8 bits of representational accuracy
None of this seems like anything that would be useful for the interpolation on a non-uniform grid which you are describing. At a minimum you would need to perform a coordinate transformation before you could use the uniform filtering mode. The amount of effort and expense would be about the same as just writing an interpolation routine yourself in user code.

Water rendering in opengl [duplicate]

This question already has answers here:
How to render ocean wave using opengl in 3D? [closed]
(2 answers)
Closed 7 years ago.
I have absolutely no idea how to render water sources (ocean, lake, etc). It's like every tutorial I come across assumes I have the basic knowledge in this subject, and therefore speaks abstractly about the issue, but I don't.
My goal is to have a height based water level in my terrain.
I can't find any good article that will help me get started.
The question is quite broad. I'd split it up into separate components and get each working in turn. Hopefully this will help narrow down what those might be, unfortunately I can only offer the higher level discussion you aren't directly after.
The wave simulation (geometry and animation):
A procedural method will give a fixed height for a position and time based on some noise function.
A very basic idea is y = sin(x) + cos(z). Some more elaborate examples are in GPUGems.
Just like in the image, you can render geometry by creating a grid, sampling heights (y) at the grid x,y positions and connecting those points with triangles.
If you explicitly store all the heights in a 2D array, you can create some pretty decent looking waves and ripples. The idea here is to update height based on the neighbouring heights, using a few simple rules. For example, each height moves towards the average neighbouring height but also tends towards the equilibrium height equals zero. For this to work well, heights will need a velocity value to give the water momentum.
I found some examples of this kind of dynamic water here:
height_v[i][j] += ((height_west+ height_east + height_south + height_north)/4 - height[i][j]);
height_v[i][j] *= damping;
height[i][j] += height_v[i][j];
Rendering:
Using alpha transparency is a great first step for water. I'd start here until your simulation is running OK. The primary effect you'll want is reflection, so I'll just cover that. Further on you'll want to scale the reflection value using the Fresnel ratio. You may want an absorption effect (like fog) underwater based on distance (see Beer's law, essentially exp(-distance * density)). Getting really fancy, you might want to render the underneath parts of the water with refraction. But back to reflections...
Probably the simplest way to render a planar reflection is stencil reflections, where you'd draw the scene from underneath the water and use the stencil buffer to only affect pixels where you've previously drawn water.
An example is here.
However, this method doesn't work when you have a bumpy surface and the reflection rays are perturbed.
Rather than render the underwater reflection view directly to the screen, you can render it to a texture. Then you have the colour information for the reflection when you render the water. The tricky part is working out where in the texture to sample after calculating the reflection vector.
An example is here.
This uses textures but just for a perfectly planar reflection.
See also: How do I draw a mirror mirroring something in OpenGL?

Qt: how do I make a field of 2d-interpolated colors?

I'm quite a beginner with c++, especially graphically related.
I would like to make an animated background for my graphicsview which looks kind of like this:
Gradient Field Airflow
The picture represents the turbulence of an airflow over an object.
The colors must be based on a matrix of values.
I can only find how to do single-direction gradients with QT.
How do I set this up? How do I get two-directional gradients?
/*edit
It has been pointed out well that technically speaking this is not a gradient, but an color interpolation on a 2d array of nodes.
*/
Well you have not provided the input data so no one knows what you really want to achieve !
if you have the flow trajectories and mass
Then you can use some particle system + heavy blurring/smoothing filtering to achieve this. For any known point along the trajectory plot a dithered circle with color depend on the mass/temp/velocity... and color scale. It should be solid in the middle and transparent on the edges. After rendering just blur/smooth the image few times and that should be it. The less points used the bigger the circles must be to cover the area nicely also can do it in multi pass and change the points coordinates randomly to improve randomness in the image...
if you have field strength/speed/temp or what ever grid values
Then it is similar to #1 also you can instead of particle system do the rendering via QUADs/Squares. The 2D linear gradient is called Bilinear Filtering
c00 -- x --> c01
|
|
y c(x,y)
|
|
V
c10 c11
where:
c00,c01,c10,c11 are corner colors
c(x,y) is color on x,y position inside square
x,y are in range <0,1> for simplicity (but you can use any with appropriate equations scaling)
Bilinear interpolation is 3x linear interpolation:
c0=c(x,0)=c00+((c01-c00)*x)
c1=c(x,1)=c10+((c11-c10)*x)
c(x,y) =c0 +((c1 -c0 )*y)
so render all pixels of the square with above computed colors and that is what you seek. This kind of filtering usually produce artifacts on the edges between squares or on diagonals to avoid that use non linear filtering or blur/smooth the final image
There is a tutorial on gradients in Qt: http://qt-project.org/doc/qt-4.8/demos-gradients.html and a class: http://harmattan-dev.nokia.com/docs/library/html/qt4/qgradient.html I have never used other than linear gradients and according to the docs, it seems there are only three basic types of gradients available in Qt: linear, radial and conical. If you cannot compose your desired gradient using these three types, then I am afraid you will need to program your image pixels by yourself. Not to forget, it might be worthy to explore if OpenGL somehow could help. Qt has some classes using OpenGL but I am not familiar with them to provide more advice.

Illumination invariant image

I try to create an illumination invariant image with openCV like in this paper here: http://www.cvc.uab.es/adas/publications/alvarez_2008.pdf
Has someone an idea how one can create that image from the log-log plot image in OpenCV?
+1 for the link to an interesting paper.
I guess I would build a function to convert to log, divide the channels, rotate by theta, and project onto one axis. Then I would build a function to measure the quality of the resulting invariant image. Then I would set up a search over theta to optimize the quality. That looks like what Alvarez is doing.
But first, I would study the Luv color space, it might be the closest approximation to this scheme that is possible without the special narrowband camera. Project the uv space onto a vector at angle theta, and see what happens.
As far as I can understand the two papers, they are proceeding from a false premise and arriving at an interesting method for getting 1D illumination invariant information from 2D (such as uv from Luv, HS from HSV, etc) color space.
They say illumination invariant, but they show a method of obtaining Color Temperature invariant information from log ratio of color pairs, say {log(R/G),log(B/G)}. You can imagine the setup, with a lamp on a dimmer, and they plot the color ratios: dim the lights, yes, the illumination changes, but so does the color temperature T.
Not to mention that light is not all blackbody color temperature Lambertian. How in the world can this method work? But their results look good.
So, on to the interesting method: Maximum Entropy
As in answer above, project the (log of) uv space onto a vector at angle theta. What should theta be? Search theta to maximize entropy of the result. That is, to get the sharpest peaks in the 1D result. Sort of like an auto-focus.
To answer your question though, use calcHist in opencv. After computing the log, of course.