Пожалуйста, объясните, как этот код удаляет шумы с изображения - PullRequest
0 голосов
/ 07 апреля 2019

Как приведенный ниже код на самом деле удаляет шумы с изображения?Я пытаюсь понять, что происходит, но не могу понять общую идею.Я попробовал это, и это работает (но не хорошо).Пожалуйста, дайте грубое объяснение.Спасибо.

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 ]

1 голос
/ 07 апреля 2019
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 пикселей по ширине (main-pixel-X +/- radius), поэтому ...

  • 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 в выходном файле на среднее значение.

1 голос
/ 07 апреля 2019

Код исследует окрестность каждого пикселя, находит среднее значение каждого компонента 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
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...