Как стать автором
Обновить

Масштабирование. Алгоритм Уменьшения и Увеличения изображения

Время на прочтение3 мин
Количество просмотров6.4K

В этой статье я хочу затронуть проблемы построения алгоритмов масштабирования изображения.

Наверняка когда вы пытались найти алгоритмы масштабирования вы находили в первую очередь что-то вроде: Существуют несколько алгоритмов самое простое это алгоритм Ближайший соседа потом билинейная, бикубическая интерполяция и т.д.

И какие могут быть проблемы?

Первая проблема

Ну начнем с того, что по сути своей масштабирование реализует только алгоритм Ближайшего соседа, оставшиеся лишь реализуют сглаживание более пикселизированого и грубого изображения. Нет вы конечно можете реализовать другие алгоритмы и без Ближайшего соседа, только ваш алгоритмом будет встроен тот же принцип.

1 Алгоритма Ближайший сосед. 2 Фильтр Ланцоша
1 Алгоритма Ближайший сосед. 2 Фильтр Ланцоша

Вторая проблема

Прекрасно казалось бы всё мы используем алгоритм ближайшего соседа, поверх используем какую-нибудь интерполяцию, либо функцию Ланцоша и воля, у нас все хорошо. Хорошо до того момента как мы не уменьшим изображение.

1.Исходное изображение, 2.Уменьшеное алгоритмом Ближайший сосед
1.Исходное изображение, 2.Уменьшеное алгоритмом Ближайший сосед

Конечно после этого мы начнем искать решение проблемы. Будем использовать разные фильтры, несколько циклов поэтапного уменьшения, и всё рано получим тот же ужасный результат.

А почему? Да потому, что сам принцип алгоритма Ближайшего соседа, не является верным для уменьшения изображения.

Я приведу аналогию: Перед нами стоит яблоко так, что мы видим, что оно состоит из сочетания зеленого и красного цвета, мы отходим на значительное расстояние и видим, наше яблоко перестаёт быть зелено-красным, теперь оно жёлтое. Почему так произошло, да потому, что яблоко теперь в меньшом площади обозрения, и зелёный с красным смешались в один желтый цвет.

Как понимаете, алгоритм Ближайший сосед не способен объединять информацию, он лишь выборочно передаёт те или иные цвета. Как если бы в дали яблоко виделось бы нам только в зеленом или красном цвете. Из-за этого, при использование алгоритма, изображение оказывается рваным.

Если это так то как передать информацию полностью? Я думаю, что кто-то уже догадался. Мы можем все пиксели попадающие в одну ячейку массива, просто привести к среднему цвету.

Вот пример алгоритма на C#

  public static Color[,] ConvertImage(Color[,] image, double percentageValue)
  {
      int width = (int)Math.Round(image.GetLength(0) * percentageValue);
      int height = (int)Math.Round(image.GetLength(1) * percentageValue);
  
      double[,,] valuesSum = new double[width, height, 4];
      int[,] quantities = new int[width, height];
  
  
      for (int y = 0; y < image.GetLength(0); y++)
      {
          int y2 = (int)Math.Ceiling(y * percentageValue);
  
          if (y2 >= width)
              y2 = width - 1;
  
          for (int x = 0; x < image.GetLength(1); x++)
          {
              int x2 = (int)Math.Ceiling(x * percentageValue);
  
              if (x2 >= height)
                  x2 = height - 1;
  
              valuesSum[y2, x2, 0] += image[y, x].A;
              valuesSum[y2, x2, 1] += image[y, x].R;
              valuesSum[y2, x2, 2] += image[y, x].G;
              valuesSum[y2, x2, 3] += image[y, x].B;
  
              quantities[y2, x2]++;
          }
      }
  
      Color[,] newImage = new Color[width, height];
  
      for (int y = 0; y < newImage.GetLength(0); y++)
      {
          for (int x = 0; x < newImage.GetLength(1); x++)
          {
              int A = (int)(valuesSum[y, x, 0] / quantities[y, x]);
              int R = (int)(valuesSum[y, x, 1] / quantities[y, x]);
              int G = (int)(valuesSum[y, x, 2] / quantities[y, x]);
              int B = (int)(valuesSum[y, x, 3] / quantities[y, x]);
  
              newImage[y, x] = Color.FromArgb(A, R, G, B);
          }
      }
  
      return newImage;
  }


Результат

Исходное изображение, 2.Уменьшеное новым алгоритмом
Исходное изображение, 2.Уменьшеное новым алгоритмом


Как видите мы получили совершенно иной итог.


И хотелось ещё добавить что, при уменьшении мы можем применить те же заглаживающие алгоритмы.

Теги:
Хабы:
Всего голосов 23: ↑11 и ↓12-1
Комментарии12

Публикации