# 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);
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

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);
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);
frameRate(120);
}

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