Results 1 to 6 of 6

Thread: Auto threshold value of monochrome conversion

  1. #1
    Join Date
    Oct 2007
    Posts
    13
    Thanks
    1
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android

    Default Auto threshold value of monochrome conversion

    Hi All,

    It's easy to convert any image to monochrome format by using QImage::convertToFormat like this:
    Qt Code:
    1. pImage.convertToFormat(QImage::Format_Mono, Qt::MonoOnly|Qt::ThresholdDither|Qt::AvoidDither);
    To copy to clipboard, switch view to plain text mode 
    but convertToFormat always guessing that the value of conversion's threshold is 255 where in some cases we need to use another threshold's value. I checked out GIMP and I noticed that it uses an automatic method for guessing threshold's value (see the example below) so I'm wondering:

    How I can convert images to monochrome format by using auto threshold's value just like GIMP conversion method?

    Original


    QImage conversion


    Automatic GIMP conversion


    P.S

    I've wrote a stupid function for converting images to monochrome by using a specified threshold's value as following but I need to know how I can automatically specify threshold's value:
    Qt Code:
    1. QImage getThresholdBW(QImage pImage, int threshold)
    2. {
    3. QImage result = pImage;
    4. result.fill(255);
    5. for(int x=0; x<pImage.width(); x++)
    6. for(int y=0; y<pImage.height(); y++)
    7. result.setPixel(x, y, qGray(pImage.pixel(x, y))>threshold?qRgb(255, 255, 255):qRgb(0, 0, 0));
    8.  
    9. return result;
    10. }
    To copy to clipboard, switch view to plain text mode 

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

    Default Re: Auto threshold value of monochrome conversion

    It either uses 127 as the threshold or if it is smarter, it first calculates an average or median of lightness (which is an equivalent of colors->levels->auto) (aka value in HSV) and uses that. Try doing colors->levels->auto on your image and then convert it to monochrome using 127 as the threshold. If it works you can repeat the same process in your application.
    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.


  3. #3
    Join Date
    Oct 2007
    Posts
    13
    Thanks
    1
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android

    Default Re: Auto threshold value of monochrome conversion

    Try doing colors->levels->auto on your image and then convert it to monochrome using 127 as the threshold. If it works
    It works.

    you can repeat the same process in your application.
    I tried to calculate the median but the resultant image isn't correct because the median value is big (about 203)... see my snippet plz:

    Qt Code:
    1. QImage result = pImage;
    2. QList<int> pixelsValues;
    3. for(int x=0; x<pImage.width();x++)
    4. {
    5. for(int y=0; y<pImage.height();y++)
    6. {
    7. QRgb rgb = pImage.pixel(x,y);
    8. QColor color(rgb);
    9. pixelsValues<<color.lightness();
    10. }
    11. }
    12. qSort(pixelsValues);
    13. int median;
    14. int count = pixelsValues.count();
    15. if(count%2==0)
    16. median = (pixelsValues[count/2]+pixelsValues[(count/2)+1]) / 2;
    17. else
    18. median = pixelsValues[count/2];
    19. threshold = median;
    20. for(int x=0; x<pImage.width(); x++)
    21. for(int y=0; y<pImage.height(); y++)
    22. result.setPixel(x, y, qGray(pImage.pixel(x, y))>threshold?qRgb(255, 255, 255):qRgb(0, 0, 0));
    23. qDebug("threshold = %d", threshold);
    24. return result;
    To copy to clipboard, switch view to plain text mode 

    P.S
    I'm using Qt 4.6.0 which has lightness function

  4. #4
    Join Date
    Oct 2007
    Posts
    13
    Thanks
    1
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android

    Default Re: Auto threshold value of monochrome conversion

    You can preview the resultant image down here:


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

    Default Re: Auto threshold value of monochrome conversion

    Try with an average. Median will tend to make 50% of your pixels white and the other 50% black. If you have one purple spot in a completely yellow picture that's probably not what you would want. Average should do better. If that doesn't help, there is a third choice: (minimum+maximum)/2 - this is exactly what colors->levels->auto should be doing.
    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.


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

    M. Bashir (26th November 2009)

  7. #6
    Join Date
    Oct 2007
    Posts
    13
    Thanks
    1
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android

    Default Re: Auto threshold value of monochrome conversion

    Average should do better
    It gave me nearly same result.

    there is a third choice: (minimum+maximum)/2 - this is exactly what colors->levels->auto should be doing.
    It's working, thanks wysota.

    Qt Code:
    1. QImage result = pImage;
    2. QList<int> pixelsValues;
    3. for(int x=0; x<pImage.width();x++)
    4. {
    5. for(int y=0; y<pImage.height();y++)
    6. {
    7. QRgb rgb = pImage.pixel(x,y);
    8. QColor color(rgb);
    9. pixelsValues<<color.lightness();
    10. }
    11. }
    12. qSort(pixelsValues);
    13. // int median;
    14. // int count = pixelsValues.count();
    15. // if(count%2==0)
    16. // median = (pixelsValues[count/2]+pixelsValues[(count/2)+1]) / 2;
    17. // else
    18. // median = pixelsValues[count/2];
    19. int median2 = (pixelsValues.first() + pixelsValues.last())/2;
    20. int threshold = median2;
    21. for(int x=0; x<pImage.width(); x++)
    22. for(int y=0; y<pImage.height(); y++)
    23. result.setPixel(x, y, qGray(pImage.pixel(x, y))>threshold?qRgb(255, 255, 255):qRgb(0, 0, 0));
    24. qDebug("threshold = %d", threshold);
    25. // result.save("c:/res.jpg");
    26. return result;
    To copy to clipboard, switch view to plain text mode 

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.