Results 1 to 7 of 7

Thread: How to do lens distortion on image?

  1. #1
    Join Date
    Aug 2010
    Posts
    99
    Qt products
    Qt4
    Platforms
    Windows
    Thanks
    3

    Default How to do lens distortion on image?

    I want to make a lens distortion effect on an image. And i am wondering; first - how to do it, and second - how fast will it be?

    The image in question is quite small, about 64x64 pixels, so i am hoping that the effect can be done in real-time. But there will be factors which will determine how fast it will be (i.e. if i use anti-aliasing to improve quality, that would slow down computation).

    I guess i will have to implement the algorithm myself, in which case i will need to know what the algorithm is. Wikipedia has some formulas on the "Optical aberration" page, but some C/C++ code would be nice .

    Also, would it be better to use OpenGL for this sort of thing? I would probably have to do the calculations on the CPU (i don't know much about them fancy pixel shaders, and not all graphics cards support that), so i don't know if that would be any faster.

    Basically, i am just trying to gauge whether this will be worth doing.
    [Window Detective] - Windows UI spy utility
    [War Thunder]

  2. #2
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Thanks
    3
    Thanked 453 Times in 435 Posts
    Wiki edits
    15

    Default Re: How to do lens distortion on image?

    Did you look at Vector Deformation Example

  3. #3
    Join Date
    Aug 2010
    Posts
    99
    Qt products
    Qt4
    Platforms
    Windows
    Thanks
    3

    Default Re: How to do lens distortion on image?

    I forgot to mention (or perhaps it wasn't clear in my first post) - i wish to do this on pixel data, not vectors. Unless that example can somehow be applied to QPixmaps as well, i didn't read it that closely. I guess i should have at least looked at how it's doing it, i sort of stopped reading once i got to "what is rendered on screen is not pixel manipulation, but modified vector representations of the glyphs themselves"
    [Window Detective] - Windows UI spy utility
    [War Thunder]

  4. #4
    Join Date
    Apr 2010
    Posts
    769
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11
    Thanks
    1
    Thanked 94 Times in 86 Posts

    Default Re: How to do lens distortion on image?

    This doesn't seem difficult. A ray passing through the simulated lens is deflected toward the center of the lens; the deflection will be greater near the center. Figure out which pixel a ray would hit and color the screen pixel that color. You only have to do a quadrant (actually, only an octant, but quadrants are easier to work with) and for such a small image you can pre-compute the deflections once; the problem then reduces to a simple array lookup for each pixel.

    You can try a linear deflection warp to start, but I'd guess a sinusoidal function might be more realistic.

  5. #5
    Join Date
    Aug 2010
    Posts
    99
    Qt products
    Qt4
    Platforms
    Windows
    Thanks
    3

    Default Re: How to do lens distortion on image?

    I have just been playing around with direct pixel manipulation using QImage::bits(), and it is quite fast. I can perform these operations in real-time in the paint event. Optimisations can be done, but for now it definitely seems possible.

    @SixDegrees: Thanks. I will have to think about the maths a bit, and i don't understand what you mean about quadrants and pre-computing deflections, but i'm sure i'll get it.
    [Window Detective] - Windows UI spy utility
    [War Thunder]

  6. #6
    Join Date
    Aug 2010
    Posts
    99
    Qt products
    Qt4
    Platforms
    Windows
    Thanks
    3

    Default Re: How to do lens distortion on image?

    I'm getting there, but still needs work.

    Here is what i have so far:
    Qt Code:
    1. /* get the_image ... */
    2.  
    3. QImage originalImage = the_image;
    4. QImage warpedImage = originalImage.copy();
    5. const QRgb* oldPixels = (QRgb*)originalImage.bits();
    6. QRgb* newPixels = (QRgb*)warpedImage.bits();
    7. const int imgWidth = warpedImage.width();
    8. const int imgHeight = warpedImage.height();
    9. const int halfWidth = imgWidth / 2;
    10. const int halfHeight = imgHeight / 2;
    11.  
    12. for (int y = 0; y < imgHeight; y++) {
    13. for (int x = 0; x < imgWidth; x++) {
    14. float cx = (float)(x - halfWidth);
    15. float cy = (float)(y - halfHeight);
    16. float radiusSquared = (cx * cx) + (cy * cy);
    17. float f = 1 - (radiusSquared * 0.0005f);
    18.  
    19. int newX = (int)(f * cx) + halfWidth;
    20. int newY = (int)(f * cy) + halfHeight;
    21.  
    22. if (newX >= 0 && newY >= 0 && newX < imgWidth && newY < imgHeight) {
    23. *(newPixels + (y * imgWidth) + x) = *(oldPixels + (newY * imgWidth) + newX);
    24. }
    25. }
    26. }
    27.  
    28. /* draw warpedImage ... */
    To copy to clipboard, switch view to plain text mode 

    The main thing is calculating the offsets (deflection) of each pixel. That is the line:
    f = 1 - (radiusSquared * scaleFactor)

    With that minus in there, the image curves out toward the edges (like this). I want it to distort the other way, like a magnifying glass. But when i change the minus to a plus, the result is not quite right. I think it is curving the image correctly, but only the middle of the image, the outside is unaffected.
    I will continue to play around with the algorithm until i get something that looks good.

    Just one more question, is that algorithm above a linear function or sinusoidal? (i think it's linear, right?).

  7. #7
    Join Date
    Aug 2010
    Posts
    99
    Qt products
    Qt4
    Platforms
    Windows
    Thanks
    3

    Default Re: How to do lens distortion on image?

    Ok, i have something now that works quite well.
    I scrapped that algorithm i posted above and instead just converted the x,y points to polar coordinates then scaled the radius appropriately and converted back to Cartesian.
    Perhaps there is a quicker way of doing that, but i am pre-calculating and caching these values for each pixel (which i assume is what SixDegrees was talking about), so speed doesn't really matter there.

    Now i just have to do anti-aliasing on the distorted image.
    [Window Detective] - Windows UI spy utility
    [War Thunder]

Similar Threads

  1. QGraphicsView ugly distortion yuck
    By genjix in forum Qt Programming
    Replies: 4
    Last Post: 23rd October 2010, 14:05
  2. Image: out of memory, returning null image
    By darek_hecpl in forum Qt for Embedded and Mobile
    Replies: 0
    Last Post: 22nd September 2010, 13:48
  3. paintEvent and the strange image distortion
    By roxton in forum Qt Programming
    Replies: 0
    Last Post: 2nd September 2010, 10:30
  4. Replies: 6
    Last Post: 21st September 2009, 10:55
  5. Replies: 3
    Last Post: 14th March 2007, 08:09

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
  •  
Qt is a trademark of The Qt Company.