Results 1 to 7 of 7

Thread: Images captured using QGLWidget::grabFrameBuffer aren't equal on different platforms

  1. #1
    Join Date
    Mar 2010
    Location
    Volcano, Big Island, Hawaii
    Posts
    10
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Images captured using QGLWidget::grabFrameBuffer aren't equal on different platforms

    I wrote a unit test which compares the contents of a frame buffer to a control image that was captured previously. When I run the unit test on my development platform, the test succeeds -- but when I transfer the unit test and the control image to another platform, the newly captured frame doesn't quite match the control image. Both platforms have the same screen resoution and color depth. What else do I have to ensure is the same on both machines before I can expect the images to comopare successfully? Or, what other method can I use to compare images that is more robust?

    Here is a code snippet:
    Qt Code:
    1. //grab the frame buffer from the QGLWidget
    2. QImage image = m_ui.m_imageWidget->grabFrameBuffer();
    3.  
    4. //Read in the control image -- was previously saved using QImage::save with png format
    5. QImage control_image("./images/controlGeoImage.png");
    6.  
    7. //Compare the test image with the expected control image
    8. QCOMPARE(image, control_image); //fails if control_image is from a different platform
    To copy to clipboard, switch view to plain text mode 

    If I look at the control image and the newly captured test image from a different platform, I can see the differences, but don't know how to avoid the differences so that I can develop the unit tests on one platform, and run them (for nightly testing) on another. See the test image and control image below:





    The bottom image, which is the newly captured test image, shows a bit of pink on the edges between the dark blue and light blue sections.

  2. #2
    Join Date
    Oct 2008
    Posts
    37
    Thanked 2 Times in 2 Posts

    Default Re: Images captured using QGLWidget::grabFrameBuffer aren't equal on different platfo

    By platform do you mean OS or hardware?

    Also, are you running the same hardware with the same version of the drivers?

  3. #3
    Join Date
    Mar 2010
    Location
    Volcano, Big Island, Hawaii
    Posts
    10
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Images captured using QGLWidget::grabFrameBuffer aren't equal on different platfo

    I'm running same OS on different hardware. Today I tried turning off hardware acceleration in OpenGL and produced a new control image that way. To the naked eye, the new control image from the development platform and the test image from the test platform now look exactly the same (ie, both look like the bottom image above). But they still don't compare successfully -- so I'm trying to figure out what's different now.

    So now that I'm using software rendering in OpenGL, do I still need to worry about whether my drivers are the same (are we talking drivers for the graphics card)?

  4. #4
    Join Date
    Mar 2006
    Location
    San Francisco, CA
    Posts
    23
    Thanks
    9
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Images captured using QGLWidget::grabFrameBuffer aren't equal on different platfo

    What about having a separate control image per platform ?

  5. #5
    Join Date
    Mar 2010
    Location
    Volcano, Big Island, Hawaii
    Posts
    10
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Images captured using QGLWidget::grabFrameBuffer aren't equal on different platfo

    A separate control image per platform will get to be messy, as there are many unit tests in the making... I'd like an elegant and robust solution to this problem. But yeah, if I can't figure it out, the separate control images would certainly work. -- but I'm holding off for something better...

  6. #6
    Join Date
    Mar 2010
    Location
    Volcano, Big Island, Hawaii
    Posts
    10
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Images captured using QGLWidget::grabFrameBuffer aren't equal on different platfo

    Well, I compared pretty closely the new control and test images that I produced with OpenGL software rendering only. I used an application called ImageMagick to create an image showing the differences. Here it is:



    When I looked at the size of the differences, I was surprised to see that almost all pixels that were different were greater by exactly 16 in one or more channel (red, green, or blue) of the test image. So I used ImageMagick again to create an image showing thresholded differences, with the threshold set to 16. Here it is:



    Percentage-wise, the differences are pretty small, once you allow for that "fuzz factor" of 16.
    So now I'm comparing my test and control images using this forgiving comparison function, that I modeled from a function that I found elsewhere on the Qt site, called "fuzzyComparePixels". For the particular case that I've been discussing, I call this function with an rPixelTolerance of 16 and an rImageTolerance of 0.5 percent:

    Qt Code:
    1. ///Compare two images. Ignores the alpha channel.
    2. ///Must be same size and format.
    3. ///@param rImage1 first image (order does not matter)
    4. ///@param rImage2 second image
    5. ///@param rPixelTolerance tolerable difference in a color channel
    6. ///@param rImageTolerance tolerable percentage of pixels above pixel tolerance
    7. ///@return true if the images compare favorable, false otherwise
    8.  
    9. const bool
    10. CompareImages(QImage& rImage1,
    11. QImage& rImage2,
    12. const uint32 rPixelTolerance,
    13. const float32 rImageTolerance)
    14. {
    15. bool success = false;
    16. if (rImage1.width() == rImage2.width() &&
    17. rImage1.height() == rImage2.height() &&
    18. rImage1.depth() == rImage2.depth() &&
    19. rImage1.format() == rImage2.format())
    20. {
    21. int32 failed_pixel_count = 0;
    22.  
    23. for (int32 y = 0; y < rImage1.height(); y++)
    24. {
    25. for (int32 x = 0; x < rImage1.width(); x++)
    26. {
    27. QRgb pixel_1 = rImage1.pixel(x,y);
    28. QRgb pixel_2 = rImage2.pixel(x,y);
    29.  
    30. uint32 redFuzz = qAbs(qRed(pixel_1) - qRed(pixel_2));
    31. uint32 greenFuzz = qAbs(qGreen(pixel_1) - qGreen(pixel_2));
    32. uint32 blueFuzz = qAbs(qBlue(pixel_1) - qBlue(pixel_2));
    33.  
    34. if (redFuzz > rPixelTolerance ||
    35. greenFuzz > rPixelTolerance ||
    36. blueFuzz > rPixelTolerance)
    37. {
    38. failed_pixel_count++;
    39. }
    40. }
    41. }
    42. float32 percent_failed =
    43. failed_pixel_count * 100.0 / (rImage1.width() * rImage1.height());
    44. qDebug("failed_pixel_count = %d, percent_failed = %f",
    45. failed_pixel_count, percent_failed);
    46. if (percent_failed <= rImageTolerance)
    47. {
    48. success = true;
    49. }
    50. }
    51. return success;
    52. }
    To copy to clipboard, switch view to plain text mode 

    I ignore the alpha channel because the alpha channel on my control and test images are totally different, with one having all "0"s in the alpha channel and the other having all "255"s. I don't know why this is. I do the GLWidget::grabFrameBuffer(bool withAlpha=false) call without an argument, allowing it to default to false. Perhaps the alpha channel initializes differently on the two platforms?

    Another interesting observation is that the test and control images that have 0 rotation involved (unlike the 10 degree rotation in the images above) seem to be much more alike. Perhaps the two platforms are using different smoothing techniques? I don't know. I checked the versions of the OpenGL and the png libraries, and they were the same on both platforms.

    So I feel that I can use the forgiving image comparison technique that I'm showing above, and still faithfully report unit test success or failure -- but I'd like to understand what causes these image differences. The images all have an image depth of 32, and the control images are stored in png format. If you have an idea of what is causing the differences, please respond.

  7. #7
    Join Date
    Jan 2006
    Location
    Sta. Eugènia de Berga (Vic - Barcelona - Spain)
    Posts
    869
    Thanks
    70
    Thanked 59 Times in 57 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Images captured using QGLWidget::grabFrameBuffer aren't equal on different platfo

    Hi,

    Are the two systems equal? Do they have the same video configuration (antialiasing, ...). I think that "grabFrameBuffer" returns you the displayed image, so if your graphics card applied an antialiasign filter, the images will be different.
    Òscar Llarch i Galán

Similar Threads

  1. TreeWidget mousePressEvent not being captured
    By sujan.dasmahapatra in forum Qt Programming
    Replies: 1
    Last Post: 10th December 2009, 06:08
  2. Forcing equal row heights in QTableWidget
    By wssddc in forum Newbie
    Replies: 2
    Last Post: 2nd November 2009, 01:16
  3. Equal scales
    By sukram in forum Qwt
    Replies: 1
    Last Post: 22nd July 2008, 07:44
  4. Making 3D Images wuthout QGLWidget
    By ashishsaryar in forum Qt Programming
    Replies: 2
    Last Post: 15th February 2008, 09:18
  5. QGLWidget::grabFrameBuffer
    By ToddAtWSU in forum Qt Programming
    Replies: 2
    Last Post: 19th December 2006, 06:13

Tags for this Thread

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.