【问题标题】:Please explain how this code removes noise from an image请解释此代码如何从图像中去除噪声
【发布时间】:2019-08-28 11:44:03
【问题描述】:

下面的代码实际上是如何从图像中去除噪点的?我试图了解发生了什么,但似乎无法掌握整体思路。我已经尝试过了,它有效(但效果不佳)。请粗略解释一下。谢谢。

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;
    }
  }
}

【问题讨论】:

    标签: c image-processing


    【解决方案1】:
    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;
    

    当我们找到一个位置时,我们是

    • n 像素向上(主像素 Y +/- 半径),
    • m 跨像素(主像素-X +/- 半径), 所以……

    • n 行大小 X 像素,

    • 加上m 这一行,是...

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

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

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

       /* 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 内的所有位置...

          curr_idx = j + i * img->sizeX;
          pixel = (red_avg << 16) + (green_avg << 8) + blue_avg;
          img->data[curr_idx] = pixel;
    

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

    【讨论】:

      【解决方案2】:

      代码探索每个像素的邻域,找到每个 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
          }
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2014-05-22
        • 2023-04-05
        • 1970-01-01
        • 2021-08-16
        • 2011-12-30
        • 2019-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多