处理语言中图像处理的卷积

时间:2021-01-10 11:17:32

标签: image-processing processing convolution

由于 Corona 情况将我的学习描述为自学,作为处理语言的新手,我没有轻松时间进入图像处理主题,更具体地说是卷积。所以我希望你能帮助我。

不幸的是,几乎无法联系到我的讲师给我留下了以下转换代码。卷积背后的理论对我来说很清楚,但我在与代码相关的理解上有很多差距。有人可以留下一行注释,以便我可以更流畅地进入代码吗?

代码如下

color convolution (int x, int y, float[][] matrix, int matrix_size, PImage img){
  float rtotal = 0.0;
  float gtotal = 0.0;
  float btotal = 0.0;
  int offset = matrix_size / 2;
  for (int i = 0; i < matrix_size; i++){
    for (int j= 0; j < matrix_size; j++){
      int xloc = x+i-offset;
      int yloc = y+j-offset;
      int loc = xloc + img.width*yloc;
  
      rtotal += (red(img.pixels[loc]) * matrix[i][j]);
      gtotal += (green(img.pixels[loc]) * matrix[i][j]);
      btotal += (blue(img.pixels[loc]) * matrix[i][j]);
  }
}
  rtotal = constrain(rtotal, 0, 255);
  gtotal = constrain(gtotal, 0, 255);
  btotal = constrain(btotal, 0, 255); 

  return color(rtotal, gtotal, btotal);

}

1 个答案:

答案 0 :(得分:4)

我必须做一些猜测,因为我对您使用的所有函数都不是很肯定,而且我不熟悉 Processing 3+ 库,但这是我最好的尝试。

color convolution (int x, int y, float[][] matrix, int matrix_size, PImage img){
    // Note: the 'matrix' parameter here will also frequently be referred to as
    // a 'window' or 'kernel' in research
    // I'm not certain what your PImage class is from, but I'll assume
    // you're using the Processing 3+ library and work off of that assumption

    // how much of each color we see within the kernel (matrix) space
    float rtotal = 0.0;
    float gtotal = 0.0;
    float btotal = 0.0;

    // this offset is to zero-center our kernel
    // the fact that we use matrix_size / 2 sort of implicitly
    // alludes to the fact that our matrix_size should be an odd-number
    // so that we can have a middle-pixel
    int offset = matrix_size / 2;

    // looping through the kernel. the fact that we use 'matrix_size'
    // as our end-condition for both dimensions means that our 'matrix' kernel
    // must always be a square
    for (int i = 0; i < matrix_size; i++){
        for (int j= 0; j < matrix_size; j++){
            // calculating the index conversion from 2D to the 1D format that PImage uses
            // refer to: https://processing.org/tutorials/pixels/
            // for a better understanding of PImage indexing (about 1/3 of the way down the page)
            // WARNING: by subtracting the offset it is possible to hit negative
            // x,y values here if you pick an x or y position less than matrix_size / 2. 
            // the same index-out-of-bounds can occur on the high end. 
            // When you convolve using a kernel of N x N size (N here would be matrix_size)
            // you can only convolve from [N / 2, Width - (N / 2)] for x and y
            int xloc = x+i-offset; 
            int yloc = y+j-offset;
            // this is the final 1D PImage index that corresponds to [xloc, yloc] in our 2D image
            // really go back up and take a look at the link if this doesn't make sense, it's pretty good
            int loc = xloc + img.width*yloc; 

            // I have to do some speculation again since I'm not certain what red(img.pixels[loc]) does
            // I'll assume it returns the red red channel of the pixel
            // this section just adds up all of the pixel colors multiplied by the value in the kernel
            rtotal += (red(img.pixels[loc]) * matrix[i][j]);
            gtotal += (green(img.pixels[loc]) * matrix[i][j]);
            btotal += (blue(img.pixels[loc]) * matrix[i][j]);
        }
    }

    // the fact that no further division or averaging happens after the for-loops implies
    // that the kernel you feed in should have balanced values for your kernel size
    // for example, a kernel that's designed to average out the color over the 3 x 3 area
    // it covers (this would be like blurring the image) would be filled with 1/9
    // in general: the kernel you're using should have a sum of 1 for all of the numbers inside
    // this is just 'in general' you can play around with not doing that, but you'll probably notice a
    // darkening effect for when the sum is less than 1, and a brightening effect if it's greater than 1
    // for more info on kernels, read this: https://en.wikipedia.org/wiki/Kernel_(image_processing)

    // I don't have the code for this constrain function,
    // but it's almost certainly just your typical clamp (constrains the values to [0, 255])
    // Note: this means that your values saturate at 0 and 255
    // if you see a lot of black or white then that means your kernel
    // probably isn't balanced as mentioned above
    rtotal = constrain(rtotal, 0, 255);
    gtotal = constrain(gtotal, 0, 255);
    btotal = constrain(btotal, 0, 255); 

    // Finished!
    return color(rtotal, gtotal, btotal);
}