请说明此代码如何消除图像中的噪点

时间:2019-04-07 00:10:01

标签: c image-processing

以下代码实际上如何去除图像中的噪点?我试图了解正在发生的事情,但似乎无法掌握总体思路。我已经尝试过了,而且效果很好(但效果不佳)。请给出一个粗略的解释。谢谢。

void averageFilter(PIXEL_ARRAY* img, PIXEL_ARRAY* orig_img, int N) 
{

  int i, j, n, m;
  int red_avg, blue_avg, green_avg;
  int radius, out_of_bounds, idx, curr_idx;
  int32_t pixel;

  if (N % 2 == 0) {
    printf("ERROR: Please use an odd sized window\n");
    exit(1);
  }

  radius = N / 2;

  for (i = 0; i < img->sizeY; i++) {
    for (j = 0; j < img->sizeX; j++) {
      out_of_bounds = 0;

      red_avg = 0;
      blue_avg = 0;
      green_avg = 0;

      for (n = i - radius; n <= i + radius; n++) {

    for (m = j - radius; m <= j + radius; m++) {
      if (n < 0 || m < 0 || n >= img->sizeY || m >= img->sizeX) {
        out_of_bounds++;
        continue;
      }
      idx = m + n * img->sizeX;
      /* Shift, mask and add */


      red_avg += ((orig_img->data[idx] >> 16) & 0xFF);
      green_avg += ((orig_img->data[idx] >> 8) & 0xFF);
      blue_avg += (orig_img->data[idx] & 0xFF);

    }
      }

      /* Divide the total sum by the amount of pixels in the window */
      red_avg /= (N * N - out_of_bounds);
      green_avg /= (N * N - out_of_bounds);
      blue_avg /= (N * N - out_of_bounds);

      /* Set the average to the current pixel */
      curr_idx = j + i * img->sizeX;
      pixel = (red_avg << 16) + (green_avg << 8) + blue_avg;
      img->data[curr_idx] = pixel;
    }
  }
}

2 个答案:

答案 0 :(得分:1)

代码探索每个像素的邻域,找到每个R,G,B分量的平均值,然后将它们写入输出图像。因此,这是一个平滑过滤器。我已经注释了代码:

void averageFilter(PIXEL_ARRAY* img, PIXEL_ARRAY* orig_img, int N) 
{

  int i, j, n, m;
  int red_avg, blue_avg, green_avg;
  int radius, out_of_bounds, idx, curr_idx;
  int32_t pixel;

  if (N % 2 == 0) {
    printf("ERROR: Please use an odd sized window\n");
    exit(1);
  }

  radius = N / 2;                                   // distance from pixel to explore

  for (i = 0; i < img->sizeY; i++) {                // parse each image pixel
    for (j = 0; j < img->sizeX; j++) {
      out_of_bounds = 0;

      red_avg = 0;                                  // init the averages
      blue_avg = 0;
      green_avg = 0;

      for (n = i - radius; n <= i + radius; n++) {  // within the area to explore

    for (m = j - radius; m <= j + radius; m++) {
      if (n < 0 || m < 0 || n >= img->sizeY || m >= img->sizeX) {   // off the map?
        out_of_bounds++;                            // count pixels off the map
        continue;                                   // and skip the summing
      }
      idx = m + n * img->sizeX;        // locate index of the pixel in source 1D array
      /* Shift, mask and add */


      red_avg += ((orig_img->data[idx] >> 16) & 0xFF);   // extract each R,G,B in the region
      green_avg += ((orig_img->data[idx] >> 8) & 0xFF);  // and sum them
      blue_avg += (orig_img->data[idx] & 0xFF);

    }
      }

      /* Divide the total sum by the amount of pixels in the window */
      red_avg /= (N * N - out_of_bounds);           // produce an average R,G,B within the region
      green_avg /= (N * N - out_of_bounds);
      blue_avg /= (N * N - out_of_bounds);

      /* Set the average to the current pixel */
      curr_idx = j + i * img->sizeX;                // locate index in destination array
      pixel = (red_avg << 16) + (green_avg << 8) + blue_avg;  // merge the components
      img->data[curr_idx] = pixel;                  // set its value to the average of the region
    }
  }
}

答案 1 :(得分:1)

loop do
  input = gets.chomp.capitalize
  break if input == ''
  input = ' - ' + input
  tasks <<  input
end



doc.bookmarks['Tasks'].insert_multiple_lines(tasks)

永远是网格中的像素...

for (i = 0; i < img->sizeY; i++) {
    for (j = 0; j < img->sizeX; j++) {`

访问像素for (n = i - radius; n <= i + radius; n++) { for (m = j - radius; m <= j + radius; m++) { 内的位置...

radius

(记住我们发现了多少)

 if (n < 0 || m < 0 || n >= img->sizeY || m >= img->sizeX) {
        out_of_bounds++;
        continue;

找到位置后,我们就

  • 向上 idx = m + n * img->sizeX; 个像素(主像素Y +/-半径),
  • n个像素(主像素X +/-半径), 所以...

  • m行,大小为X个像素,

  • 此行加n是...

m:我们所在位置的像素索引

idx

从我们访问的每个位置统计原始图像的RGB数据

 red_avg += ((orig_img->data[idx] >> 16) & 0xFF);
 green_avg += ((orig_img->data[idx] >> 8) & 0xFF);
 blue_avg += (orig_img->data[idx] & 0xFF);

...平均每个主要像素 /* Divide the total sum by the amount of pixels in the window */ red_avg /= (N * N - out_of_bounds); green_avg /= (N * N - out_of_bounds); blue_avg /= (N * N - out_of_bounds); /* Set the average to the current pixel */ 内的所有位置...

radius

...然后将输出文件中的main-pixel-index设置为平均值。