I need help with optimization of a basic sharpening algorithm

Hi, one of my recent projects led me into making a sharpening filter, but I am having problems making it run smoothly.
The code is modified from the (also very slow) sharpening code found in this processing tutorial on pixels

It makes a lot of sense why it is slow, seeing it go through every pixel many times, but it doesn’t make sense how such a normally light effect in many games is so demanding here.

float[][] matrix = { { -1, -1, -1 },
                     { -1,  9, -1 },
                     { -1, -1, -1 } }; 
void sharpen(){
  PImage temp = new PImage(width,height,RGB);
  loadPixels();
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++ ) {
      color c = convolution(x,y,matrix,3);
      int loc = x + y*width;
      temp.pixels[loc] = c;
    }
  }
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++ ) {
        pixels[x+y*width] = temp.pixels[x+y*width];
    }
  }
  updatePixels();
}

color convolution(int x, int y, float[][] matrix, int matrixsize) {
  float rtotal = 0.0;
  float gtotal = 0.0;
  float btotal = 0.0;
  int offset = matrixsize / 2;
  // Loop through convolution matrix
  for (int i = 0; i < matrixsize; i++){
    for (int j= 0; j < matrixsize; j++){
      // What pixel are we testing
      int xloc = x+i-offset;
      int yloc = y+j-offset;
      int loc = xloc + width*yloc;
      // Make sure we have not walked off the edge of the pixel array
      loc = constrain(loc,0,pixels.length-1);
      // Calculate the convolution
      // We sum all the neighboring pixels multiplied by the values in the convolution matrix.
      rtotal += (red(pixels[loc]) * matrix[i][j]);
      gtotal += (green(pixels[loc]) * matrix[i][j]);
      btotal += (blue(pixels[loc]) * matrix[i][j]);
    }
  }
  // Make sure RGB is within range
  rtotal = constrain(rtotal,0,255);
  gtotal = constrain(gtotal,0,255);
  btotal = constrain(btotal,0,255);
  // Return the resulting color
  return color(rtotal,gtotal,btotal);
}
2 Likes

please explain more,
a questionable way to use it ( not reading your code ) would be

/** start from example
 * Load and Display 
 */

PImage img;

void setup() {
  size(640, 360);
  img = loadImage("moonwalk.jpg");
  frameRate(120);                            // get 120 for image only 
}

void draw() {
  surface.setTitle(nf(frameRate,0,1)+" FPS");
  image(img, 0, 0);
  sharpen();                    // but with "sharpen()" get still 80 FPS
}

but no problem here

add try different renderer AND add some load ( paint 5000 circles over the picture )

/** start from example Image: Load and Display  */

PImage img;
int many = 5000;                    // if load draw many circles..
boolean load   = false;
boolean filter = false;

//__________________________________________________
//         |  JAVA2D   |  FX2D   |  P2D   |  P3D   |
//_________|___________|_________|________|________|
// image   |    120    |   120   |  120   |  120   |
// filter  |     86    |    83bad|   60   |   60   |
// + load  |     23    |   120   |   42   |   42   |
// fil+load|     19    |    45   |   27   |   27   |
//_________|___________|_________|________|________|

void setup() {
  size(640, 360);
  //  size(640, 360, FX2D);
  //  size(640, 360,P2D);
  //  size(640, 360,P3D);
  img = loadImage("moonwalk.jpg");
  frameRate(120);
  println("[f] filter: "+filter+" [l] load: "+load);
}

void draw() {
  surface.setTitle(nf(frameRate, 0, 1)+" FPS");
  image(img, 0, 0);
  if ( load ) for ( int i = 0; i < many; i++ ) circle(20+i%15, 20+ i%13, 10);
  if ( filter ) sharpen();
}

1 Like

I am using this filter for a game, and the use of the filter on the main menu featuring 2 moving objects(when framerate is uncapped) cuts the frame rate dramatically. ~600fps to 8fps.
What I am asking here is help in reducing that drop in fps

For realtime performance, you’ll need to do this in a shader. That way, instead of looping through every pixel one at a time, the GPU can run the filter on every pixel simultaneously.

2 Likes

Im going to leave this topic now, but Ill leave anyone in the future who needs this what I did find:

  1. rufsketch1’s link goes in detail how shaders work in proccesing 3
  1. a sharpening filter developed for an older version of proccesing
    Processing-Shader-Examples/sharpen_shader at master · atduskgreg/Processing-Shader-Examples · GitHub
  2. another sharpening filter developed for an older version of processing
    GitHub - couleurs/glsl-sharpen: GLSL module for image sharpening

hopefully this helps in the future

3 Likes