Results 1 to 3 of 3

Thread: Advice needed - QImage vs. OpenGL for 2D data display

  1. #1
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Advice needed - QImage vs. OpenGL for 2D data display

    I have scientific data in the form of x vs. y with a color gradient that assigns a color to each (x, y) pair (the z axis). The problem is that the aspect ratio is crazy. There might be 100K points (or more) in the x dimension, but only 400 points in the y dimension. Because the data matrix is sparse, most of the z axis values will be zero. The z-values are "spiky" - if you scan along the x axis, there will be sharp ~Lorentzian spikes for 10 or so points separated by hundreds of zeros. The spikes might extend for 3 or 4 points in the y dimension.

    I need to implement a 2D display that has the ability to display the entire matrix in a "normal" sized window, say 1000 x 1000 pixels. This will generally require expanding the y range so that 400 points fill a 1000 point range. That's not hard and can be implemented with interpolation.

    What about the x axis? Given that maybe 100 data points will map to the same x pixel, what is the best choice? Choose the maximum z value in the range? The average z value? It would be confusing to the user if, as the plot was zoomed in, peaks suddenly started appearing where there were no peaks at lower zoom level.

    Zooming has to be fast. Resampling a section of a 400 x 100K point matrix into a 1000 x 1000 pixel image could take forever if every pixel has to be recomputed each time. It is sparse data, so I really don't want to have to explode it into a 400 x 100K matrix where most of it is zero.

    Finally, what is the best way to implement this for display? Using a QImage? Or implementing it as a texture in OpenGL? Are there GPU-side OpenGL mechanisms to create a texture using the full data matrix size (400 x 100K) that will allow me to map and zoom without huge CPU-side overhead? I could constrain the z-axis gradient to 0 - 255, so a matrix of that size would only be 40 MB.

    If would appreciate any advice.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  2. #2
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Advice needed - QImage vs. OpenGL for 2D data display

    Quote Originally Posted by d_stranz View Post
    This will generally require expanding the y range so that 400 points fill a 1000 point range. That's not hard and can be implemented with interpolation.
    You don't necessarily have to expand the y range to fit the screen in the y direction. You could always show a stripe of 1000 x 400 squares on the screen rather than unnaturally y-elongated rectangles.

    Quote Originally Posted by d_stranz View Post
    What about the x axis? Given that maybe 100 data points will map to the same x pixel, what is the best choice? It would be confusing to the user if, as the plot was zoomed in, peaks suddenly started appearing where there were no peaks at lower zoom level.
    Yap! Are your spikes always in the positive direction? If yes, I think it's best if you select the maximum z-value that has been mapped to the same pixel and show that. This way no spikes will be hidden. However, it is up to your application how interesting these spikes are. Say if you map 1000 values to the same pixel, 999 are zeros and one is a spike, would you want to see the spike or not? This is a choice you have to make. If yes, select the maximum. If not, average the z values or use a soft max function maybe. If your spikes occur in the positive AND the negative direction, selecting just the most extreme z-value in one pixel may eradicate a second spike in the opposite direction. In this case, I would declare the smallest unit to be 2 pixels, one of them showing the most extreme positive value and the other the most extreme negative value in the bin.


    Quote Originally Posted by d_stranz View Post
    Zooming has to be fast. Resampling a section of a 400 x 100K point matrix into a 1000 x 1000 pixel image could take forever if every pixel has to be recomputed each time. It is sparse data, so I really don't want to have to explode it into a 400 x 100K matrix where most of it is zero.
    Do you have any meta information about the sparse structure, for example an index of the starting points of the non-zero blocks and the zero blocks for each line? Yes, precomputing such a data structure, and then using it for a (more complicated) resampling algorithm could save you tremendous amounts of computation time. Obviously, your most critical use case is when the entire matrix is on the screen, and all 100K pixels need to be mapped to 1000. When the user zooms in, a smaller amount of values will be mapped to one pixel, and not the entire matrix will be seen on the screen, which means you will need a pan operation. You can accelerate the sampling in this case (in combination with exploiting the sparse structure) by computing the bounding box of the actually visible portion of the matrix, and mapping only those cells to the visible resolution.

    However, if you end up not needing a special operation for the visualization of the spike at low zoom levels, you could just render the whole matrix once into a QImage or QPixmap, and then just use screen transformations (QTransform) to implement your panning and scaling. This would be easy and very fast.


    Quote Originally Posted by d_stranz View Post
    Finally, what is the best way to implement this for display? Using a QImage? Or implementing it as a texture in OpenGL?
    I have once faced a similar task where I had to render a computationally demanding image pixel by pixel and made good experiences with rendering offline into a QImage and then showing that on the screen, or even drawing additional things on top of it. This ended up being fast enough for my application. I have no clue about using OpenGL textures and shaders, so hopefully someone else can throw in another penny concerning that approach.

    Cheers
    Cruz

  3. The following user says thank you to Cruz for this useful post:

    d_stranz (1st September 2016)

  4. #3
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Advice needed - QImage vs. OpenGL for 2D data display

    @Cruz - thanks for the feedback.

    Are your spikes always in the positive direction?
    All data points are positive, so no negative / positive concerns. I'm leaning towards showing the maximum value.

    Do you have any meta information about the sparse structure
    Not really. The data are an array of paired arrays of sparse points. That is, there is a master y-array containing the y-axis coordinates. For each y-axis value, there are x and z arrays. The z-array contains only the non-zero intensity values, plus a pair of zeros on each end of a block to serve as a delimiter. The x-array contains the positions of each of the z-array points.

    So there is potentially sparseness in both x- and y-dimensions. If there are no non-zero intensity points along the x-axis for a given y coordinate, then that coordinate (and corresponding x- and z-arrays) is omitted.

    precomputing such a data structure
    Both x- and y-arrays are sorted in increasing coordinate order, so binary search might be as effective. If I do precompute something, I am thinking about a quadtree-like approach that stores the maximum z-value at each level of detail and stops when all of the pixels within a given region are equal-valued. Have to think more on that.

    rendering offline into a QImage
    My current plan as well. I was reading up on OpenGL textures yesterday, and there's more to learn than I care to learn at this point.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. detecting the width of column needed to display data
    By mentalmushroom in forum Qt Programming
    Replies: 0
    Last Post: 17th March 2011, 15:43
  2. Advice needed for QT application architecture
    By hubbobubbo in forum Qt Programming
    Replies: 0
    Last Post: 14th December 2009, 11:30
  3. Qtopia H/w Advice needed
    By void* in forum Qt for Embedded and Mobile
    Replies: 1
    Last Post: 19th January 2007, 11:25
  4. Dynamic Data Display with OpenGL
    By showhand in forum Qt Programming
    Replies: 3
    Last Post: 14th March 2006, 01:17
  5. Practical QTreeView: Advice needed
    By Jojo in forum Qt Programming
    Replies: 13
    Last Post: 20th February 2006, 20:28

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.