I need some help with image filters

I don't understand what is wrong here, I am trying to use a matrix to apply some basic filters to images but I would like to modify the PImagedirectly instead of the pixels on the canvas itself by using image.pixels[] instead of just pixels[], however, I do not really know if I am right about that anyways.

Here is Image_Filters

PImage img; //<>// //<>// //<>// //<>// //<>//

void setup()
{
  size(600, 600);
  img = loadImage("2.jpg");
  surface.setSize(img.width, img.height);
  noLoop();
}

void draw()
{
  test(img);
  image(img, 0, 0);
}

and here is testDraw

void test(PImage image)
{
  PImage temp = image;

  float kernel[][] = { {-1, -1, -1}, //Outlines
    {-1, 8, -1}, 
    {-1, -1, -1} };

  //float kernel[][] = { {0.0625, 0.125, 0.0625}, //Blur
  //  {0.125, 0.25, 0.125}, 
  //  {0.0625, 0.125, 0.0625} };

  temp.loadPixels();
  for (int x = 0; x < image.width; x++)
  {
    for (int y = 0; y < image.height; y++)
    {
      color newColor = applyFilter(x, y, kernel, temp);
      img.pixels[x + y * image.width] = newColor;
    }
  }
  img.updatePixels();
}

color applyFilter(int x, int y, float matrix[][], PImage image)
{
  float rTotal = 0;
  float gTotal = 0;
  float bTotal = 0;

  for (int i = 0; i < 3; i++)
  {
    for (int j = 0; j < 3; j++)
    {
      int location = constrain((x + i - 1) + (y + j - 1) * image.width, 
        0, image.pixels.length - 1);
      rTotal += (image.pixels[location] >> 16 & 0xFF) * matrix[i][j];
      gTotal += (image.pixels[location] >> 8 & 0xFF) * matrix[i][j];
      bTotal += (image.pixels[location] & 0xFF) * matrix[i][j];
    }
  }
  rTotal = constrain(rTotal, 0, 255);
  gTotal = constrain(gTotal, 0, 255);
  bTotal = constrain(bTotal, 0, 255);
  return color(rTotal, gTotal, bTotal);
}

Okay, this is the problem...

Original:2

Filter Applied:

something9000

Also, can someone explain what //<>// at the top of my main file is for? Processing did that by itself.

If I forgot to explain something please just ask.

Thank you very much for your help.

Tagged:

Answers

  • You are updating the pixels as you go along. So the calculation for one pixel may include values of previous pixels that you've already processed rather than the original values.

    Try working on a copy of the photo. Maybe get rid of the img. From lines 19, 22, use the canvas for the result.

  • Answer ✓

    Good point @koogs.

    @mysteriousLynx Here is a new version of the code. Notice the changes.

    Kf

    PImage img;
    
    void settings()
    {
      img = loadImage("2.jpg");   //CHANGE++++++++++++++
      size(img.width, img.height);
    }
    
    void setup() {
      noLoop();
    }
    
    void draw()
    {
      test(img);
      image(img, 0, 0);
    }
    
    void test(PImage image)
    {
      PImage tmp=image.get();   //CHANGE++++++++++++++
      float kernel[][] = { {-1, -1, -1}, //Outlines
        {-1, 8, -1}, 
        {-1, -1, -1} };
    
    
      image.loadPixels();                       //CHANGE++++++++++++++
      for (int x = 1; x < image.width-1; x++)   //CHANGE++++++++++++++
      {
        for (int y = 1; y < image.height-1; y++)  //CHANGE++++++++++++++
        {
          color newColor = applyFilter(x, y, kernel, tmp);
          image.pixels[x + y * image.width] = newColor;
        }
      }
      image.updatePixels();
    }
    
    color applyFilter(int x, int y, float matrix[][], PImage image)
    {
      float rTotal = 0;
      float gTotal = 0;
      float bTotal = 0;
    
      for (int i = 0; i < 3; i++)
      {
        for (int j = 0; j < 3; j++)
        {
          int location = (x + i - 1) + (y + j - 1) * image.width;          //CHANGE++++++++++++++
          rTotal += (image.pixels[location] >> 16 & 0xFF) * matrix[i][j];
          gTotal += (image.pixels[location] >> 8 & 0xFF) * matrix[i][j];
          bTotal += (image.pixels[location] & 0xFF) * matrix[i][j];
        }
      }
      //rTotal = constrain(rTotal, 0, 255);
      //gTotal = constrain(gTotal, 0, 255);
      //bTotal = constrain(bTotal, 0, 255);
    
      return color(rTotal, gTotal, bTotal); 
    }
    
Sign In or Register to comment.