Results 1 to 9 of 9

Thread: Multithreaded per pixel operations on QImage

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Multithreaded per pixel operations on QImage

    setPixel is slow, use QImage::scanLine() instead. You won't need to protect it with a mutex.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  2. #2
    Join Date
    Sep 2009
    Posts
    5
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Multithreaded per pixel operations on QImage

    Thx for the clue. I just implemented it and ... the same patterns again! And again a mutex solves the pattern problem but slows the whole thing down
    This works now, and with ~7sec runtime its faster then with setPixel, but still slower than without multithreading (~2sec) -_-
    Qt Code:
    1. void Scan::convertToGrayscale(int from, int to) {
    2. int temp;
    3. for (int i=from; i<to; i++) {
    4. for (int j=0; j<imgOrig->height(); j++) {
    5. temp = qGray(imgOrig->pixel(i, j));
    6. mutex.lock();
    7. //imgDone->setPixel(i, j, qRgb(temp, temp, temp));
    8. *((QRgb*) imgDone->scanLine(j)+i) = qRgb(temp, temp, temp);
    9. mutex.unlock();
    10. }
    11. }
    12. }
    To copy to clipboard, switch view to plain text mode 
    I'll replace the pixel() function with scanline too, but the general problem of being slower with multiple threads than with only one still exists :/ Any Ideas about that? ^^

  3. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Multithreaded per pixel operations on QImage

    This works for me quite well:
    Qt Code:
    1. #include <QtGui>
    2.  
    3.  
    4. struct ImageRef {
    5. QRgb *data;
    6. int width;
    7. };
    8.  
    9. void convertToGS(const ImageRef &ref){
    10. for(int i=0;i<ref.width;i++){
    11. int gray = qGray(ref.data[i]);
    12. ref.data[i] = qRgb(gray, gray, gray);
    13. }
    14. }
    15.  
    16. int main(int argc, char **argv){
    17. if(argc<2) return 1;
    18. QApplication app(argc, argv);
    19. QImage img(argv[1]);
    20. QList<ImageRef> refs;
    21. for(int i=0;i<img.height();i++){
    22. ImageRef ref;
    23. ref.data = (QRgb*)img.scanLine(i);
    24. ref.width = img.width();
    25. refs << ref;
    26. }
    27. QtConcurrent::blockingMap(refs, convertToGS);
    28. QLabel l;
    29. l.setPixmap(QPixmap::fromImage(img));
    30. l.show();
    31. return app.exec();
    32. }
    To copy to clipboard, switch view to plain text mode 

    Multithreaded version takes 7ms as opposed to singlethreaded version that takes 12ms to convert a 1600x1200 image to grayscale.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  4. The following user says thank you to wysota for this useful post:

    N¤X (14th September 2009)

  5. #4
    Join Date
    Sep 2009
    Posts
    5
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Multithreaded per pixel operations on QImage

    Thank you, this really looks nice and clean! I will use this in the programm
    But there still remains one problem: The slowest function of my programm mainly consists of a 2-pass algorithm that runs on scanlines, in one pass on horizontal ones and in the other pass on vertical ones. Due to the structure of QImages the direct accessible scanlines are all horizontal, so I can only use your solution in one pass.
    I'll try if it still works if you don't overwrite the picture data but paint the result in a new one (the write-to-another-picture-operation was the problem from the beginning -_-). Then i could write the result of the first pass transposed into another Picture and just run the same operations over the new picture to get the final result... I'll write when I tried this!

  6. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Multithreaded per pixel operations on QImage

    Quote Originally Posted by N¤X View Post
    Thank you, this really looks nice and clean! I will use this in the programm
    But there still remains one problem: The slowest function of my programm mainly consists of a 2-pass algorithm that runs on scanlines, in one pass on horizontal ones and in the other pass on vertical ones. Due to the structure of QImages the direct accessible scanlines are all horizontal, so I can only use your solution in one pass.
    No, that's not true. After the horizontal pass transpose the image and use scanlines again. Then transpose it back. You'll get improved cpu cache performance as well (thanks to Ariya for making me aware of that) and as a result it will probably be faster than operating on the picture directly.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


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.