Results 1 to 6 of 6

Thread: Convolution filter

  1. #1
    Join Date
    Mar 2008
    Location
    France
    Posts
    149
    Thanks
    2
    Thanked 21 Times in 21 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Convolution filter

    Hello,

    I need to implement an edge dectection filter on an image.

    i've managed to put all the Qrgb colors of the image in a table (matrice_pixel[height] [width] ).

    My filter is kernel[3][3] .

    But i can't get it work properly when i mutiply the two tables.

    Any idea?

    Qt Code:
    1. QRgb **matrice_pixel = new QRgb*[height];
    2. for (int i = 0; i <height; i++){
    3. matrice_pixel[i] = new QRgb[width];
    4. }
    5.  
    6. /// Getting the colors
    7. for ( int i=0; i<height; i++ ) {
    8. uchar *p = source.scanLine(i);
    9. for (int j = 0; j< width;j ++) {
    10. int blue = int(*p++);
    11. int green = int(*p++);
    12. int red = int(*p++);
    13. int alpha = int(*p++);
    14. QRgb rgbValue = qRgba(red,green,blue, alpha);
    15. matrice_pixel[i][j] = rgbValue;
    16. }
    17.  
    18. for (int x = 1; x<width ;++x)
    19. {
    20. for (int y= 1; y< height; ++y)
    21. {
    22. int red = 0, green = 0, blue = 0;
    23. //multiply every value of the filter with corresponding image pixel
    24. for(int kernelX = 0; kernelX < kernelWidth; kernelX++)
    25. {
    26. for(int kernelY = 0; kernelY < kernelHeight; kernelY++){
    27.  
    28. red += qRed(matrice_pixel[x][ y] ) * kernel[kernelX][kernelY];
    29. green += qGreen(matrice_pixel[x][y]) * kernel[kernelX][kernelY];
    30. blue += qBlue(matrice_pixel[x] [ y]) * kernel[kernelX][kernelY];
    31. }
    32. //truncate values smaller than zero and larger than 255
    33. red = qMin(qMax(int(factor * red + bias), 0), 255);
    34. green= qMin(qMax(int(factor * green + bias), 0), 255);
    35. blue= qMin(qMax(int(factor * blue + bias), 0), 255);
    36. QRgb rgbValue = qRgb(red,green,blue);
    37. img.setPixel(x,y, rgbValue);
    38.  
    39. }
    40. }
    41. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by wysota; 20th October 2009 at 20:47. Reason: missing [code] tags

  2. #2
    Join Date
    Aug 2008
    Location
    Algarve, Portugal
    Posts
    288
    Thanks
    23
    Thanked 32 Times in 28 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60

    Default Re: Convolution filter

    But i can't get it work properly when i mutiply the two tables.
    I am assuming that it compiles fine without errors, so its a logical error. You are the autor so you have to have the patiente and the trouble to debug your aplication, because you are the one who knows what your program its supose to do. Debugging isnt fun but that the way it goes.

  3. #3
    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: Convolution filter

    According to me your algorithm is simply incorrect. To apply a convolution filter you need to consider not only the current pixel (x,y) but also its neighbours.

    Convolution for a single pixel should look more or less like this:
    Qt Code:
    1. QRgb convolute(const QList<int> &kernel, const QImage &image, int x, int y){
    2. // assuming kernel is 3x3
    3. int total = 0;
    4. int red = qRed(image.pixel(x,y));
    5. int green = qGreen(image.pixel(x,y));
    6. int blue = qBlue(image.pixel(x,y));
    7. for(int r = -1 ; r<=1; ++r){
    8. for(int c = -1; c<=1; ++c){
    9. int kerVal = kernel.at((1+r)*3+(1+c));
    10. total+=kerVal;
    11. red += qRed(image.pixel(x+c, y+r));
    12. green += qGreen(image.pixel(x+c, y+r));
    13. blue += qBlue(image.pixel(x+c, y+r));
    14. }
    15. }
    16. return QRgb(qBound(0, red/total, 255), qBound(0, green/total, 255), qBound(0, blue/total, 255));
    17. }
    To copy to clipboard, switch view to plain text mode 

    Then you have to use the above method (provided it's correct) to get values for all pixels of the image (watch out for borders as the above function doesn't handle them) and then apply them on the destination image (you can't modify the original image "in place").

    Edit: Here is something that actually seems to work.

    Qt Code:
    1. #include <QtGui>
    2.  
    3. QRgb convolute(const QList<int> &kernel, const QImage &image, int x, int y){
    4. int kernelsize = sqrt(kernel.size());
    5. qreal total = 0;
    6. qreal red = 0;
    7. qreal green = 0;
    8. qreal blue = 0;
    9. for(int r = -kernelsize/2 ; r<=kernelsize/2; ++r){
    10. for(int c = -kernelsize/2; c<=kernelsize/2; ++c){
    11. int kerVal = kernel.at((kernelsize/2+r)*kernelsize+(kernelsize/2+c));
    12. total+=kerVal;
    13. red += qRed(image.pixel(x+c, y+r))*kerVal;
    14. green += qGreen(image.pixel(x+c, y+r))*kerVal;
    15. blue += qBlue(image.pixel(x+c, y+r))*kerVal;
    16. }
    17. }
    18. if(total==0)
    19. return qRgb(qBound(0, qRound(red), 255), qBound(0, qRound(green), 255), qBound(0, qRound(blue), 255));
    20. return qRgb(qBound(0, qRound(red/total), 255), qBound(0, qRound(green/total), 255), qBound(0, qRound(blue/total), 255));
    21. }
    22.  
    23. int main(int argc, char **argv){
    24. QApplication app(argc, argv);
    25. QImage img(argv[1]);
    26. QImage dest = img;
    27. QList<int> sharpen, blur, laplace;
    28.  
    29.  
    30. sharpen << 0 << 0 << 0 << 0 << 0
    31. << 0 << 0 << -1 << 0 << 0
    32. << 0 << -1 << 5 << -1 << 0
    33. << 0 << 0 << -1 << 0 << 0
    34. << 0 << 0 << 0 << 0 << 0;
    35.  
    36. blur << 0 << 0 << 1 << 0 << 0
    37. << 0 << 1 << 3 << 1 << 0
    38. << 1 << 3 << 7 << 3 << 1
    39. << 0 << 1 << 3 << 1 << 0
    40. << 0 << 0 << 1 << 0 << 0;
    41.  
    42. laplace << -1 << -1 << -1 << -1 << -1
    43. << -1 << -1 << -1 << -1 << -1
    44. << -1 << -1 << 24 << -1 << -1
    45. << -1 << -1 << -1 << -1 << -1
    46. << -1 << -1 << -1 << -1 << -1;
    47.  
    48. for(int r=2;r<img.height()-2;r++){
    49. for(int c=2;c<img.width()-2;c++){
    50. dest.setPixel(c, r, convolute(sharpen, img, c, r));
    51. }
    52. }
    53. QLabel label;
    54. label.setPixmap(QPixmap::fromImage(dest));
    55. label.show();
    56. QLabel lab2;
    57. lab2.setPixmap(QPixmap::fromImage(img));
    58. lab2.show();
    59. return app.exec();
    60. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by wysota; 21st October 2009 at 00:44.
    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:

    toutarrive (21st October 2009)

  5. #4
    Join Date
    Mar 2008
    Location
    France
    Posts
    149
    Thanks
    2
    Thanked 21 Times in 21 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Convolution filter

    Hello wysota,

    Thanks for your help, i'll try it out right now. And let you know about the process.

  6. #5
    Join Date
    Mar 2008
    Location
    France
    Posts
    149
    Thanks
    2
    Thanked 21 Times in 21 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Convolution filter

    It works fine.

    The processing speed for 3x3 filters is not so bad but can become an issue for heavy image and 5x5 filter or greater.

    I was wandering if it was possible to limit the convolute(...) calls ?

    I found this article : http://www.codeproject.com/KB/GDI-pl...rpfilters.aspx

    What do you think of it?

    Regards.

  7. #6
    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: Convolution filter

    If you want speed then I would do convolutions in GPUs, either through shaders or CUDA/OpenCL.

    You have to process every pixel so there is not much to limit.
    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.


Similar Threads

  1. Q3Table event filter problem
    By batileon in forum Qt Programming
    Replies: 2
    Last Post: 27th August 2008, 11:40
  2. Optimizing filterAcceptsRow() to filter a tree
    By vfernandez in forum Qt Programming
    Replies: 1
    Last Post: 4th January 2007, 13:50
  3. Replies: 9
    Last Post: 31st March 2006, 14:07
  4. filter processEvents
    By sreedhar in forum Qt Programming
    Replies: 1
    Last Post: 23rd March 2006, 12:16
  5. Replies: 9
    Last Post: 5th March 2006, 04:31

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.