Рубрики
Без рубрики

Упрощенное представление об обработке изображений

Цифровая обработка изображений – это использование цифрового компьютера для обработки цифровых изображений через алгористы … Tagged с Python, программированием, учебником, новичками.

Цифровая обработка изображений Использование Цифровой компьютер для обработки Цифровые изображения через Алгоритм Анкет ~ Определение прямо с страницы из Википедии

Давайте начнем с упрощения понимания Обработка изображений и дальше, дальше с алгоритмами изображения и различными процессами, за которыми следует реализовать их, используя Pil Библиотека (довольно популярный пакет Python!).

Кредиты GIF: Google

Обработка изображений Это просто простой способ взглянуть на цифровое изображение, будь то серого масштабированного или окрашенного или какого -либо различного режима и выполнять различные операции/процессы, такие как масштабирование изображений/изменение размера, вращение, обрезка и настройка контраста, а также многие такие знакомые операции/процессы.

Предоставление всей таблицы контента, так что вы можете выбрать, какую тему вы хотите прочитать! Наслаждайся чтением. 😁

  1. Предварительные условия
  2. О пил
  3. Представление изображения и его режимы
    1. Реализация PIL
  4. Принципы обработки изображений
    1. Ближайший сосед
    2. Билинейная интерполяция
    3. Бикубическая интерполяция
    4. Метод свертки
  5. Трансформация с PIL
    1. Изменение размера изображения
    2. Вращающее изображение

Прежде чем начать что -нибудь, сделайте это!

В этом уроке, чтобы выполнить различную обработку изображений на различных изображениях, мы используем библиотеку PIL Python. Теперь, конечно, PIL не просто предварительно установлен на вашей машине. Таким образом, мы должны установить питон , пип и последний и самый важный, Pil Анкет

Если на вашем компьютере установлена Anaconda, вам не нужно делать какие -либо шаги, упомянутые ниже.

Когда вы загружаете Python , PIP устанавливается вместе с ним.

Для установки PIL мы установим подушку (подушка – это вилка PIL):

$ pip install Pillow

Если вы хотите кодировать бок о бок вместе с этим блогом, я бы посоветовал сделать следующее в вашем терминале:

$ mkdir pil-image-processing && cd pil-image-processing
$ mkdir images

Мы будем писать программы в рамках Pil-Image-обработка каталог. Вы можете использовать любой редактор кода, однако я буду использовать вим .

Кроме того, если вы хотите использовать те же изображения, что и в этом блоге, вы можете скачать Значок YouTube и Сансет картина и поместите их в свой изображения папка.

Пил Библиотека

Я кратко расскажу о том, что такое библиотека PIL и что мы рассмотрим с ней.

Библиотека PIL – это довольно популярный пакет, предоставленный Python, который обрабатывает всю обработку изображений и функции, которые я упоминал ранее. Это вкратце называется Подушка Также (я не знаю почему!).

Подушка – это «дружелюбная» пил -форк Алекса Кларка и участников. ~ Как упомянуто в документация

Представление изображения и его режимы

Pixel – самый маленький и самый важный компонент изображения. Коллекция пикселей делает изображение вообще. Значение пикселя всегда варьируется от 0-255 Анкет

Кредиты с картинками: Google

Изображение всегда имеет ширину (w) и высоту (h) и может быть понято с помощью его сравнения с помощью матрицы с w Rows и C -столбцами.

Мы перейдем на шаг дальше, чтобы понять различные режимы изображений. Ранее я упоминал, что изображение может быть представлено через матрицу. Матрица двухмерная, и эта единственная матрица образует одну канал изображения . Это новый термин предупреждение!

Когда мы заполняем матрицу в одноканале со значениями в диапазоне от 0-255 , это сформирует Серкальное изображение Анкет Большой Итак, теперь мы достигли уровня, где мы создали изображение в сети. Размер изображения в сети просто представлен с Ширина x Высота формат.

Кредиты с картинками: Google

Давайте перейдем к формированию цветных цифровых изображений, наблюдаемых в наши дни.

Для понимания цветных изображений мы пойдем в Legos. В Legos мы строим башню, разместив один Lego на другого. Таким образом, каждый LEGO похож на одноканальный. На RGB/цветных изображениях у нас есть 3 канала, которые расположены друг на друга, чтобы создать одно изображение.

В RGB у нас есть красные, зеленые и синие каналы. Каждый из этих каналов заполнен значениями от 0-255. Вместе, когда эти каналы размещены вместе, мы получаем цветное изображение. Это так же просто, как теоретически. На практике мы знаем, что изображение имеет ширину (W), представленную как ряды и высота (H), представленная в виде столбцов, но на изображении RGB нам также необходимо упомянуть каналы (C).

Размер изображения RGB представлен как Ширина x Высота x каналы Анкет

Кредиты с картинками: Google

Существуют различные другие режимы, кроме RGB и серого, таких как CMYK и RGB (и многие другие).

Rgba => rgb + alpha lchannel (обрабатывает непрозрачность изображения)

Реализация PIL для разных режимов

В PIL есть несколько шорт -кодов для моды В их документации, с которой мы будем ссылаться и выполнять простые операции.

1. Преобразовать любой формат изображения в формат серого

from PIL import Image
img = Image.open('images/image.png').convert('LA')
img.save('images/greyscale.png')

Теперь это только что преобразовало наше цветное изображение в Greyscale, черт возьми! Я объясню, что делает этот код:

  1. Импортировать Изображение Пакет из библиотеки PIL для использования встроенных функций.
  2. Открываем изображение применить La Режим для преобразования в GreyScale и назначить его переменной img Анкет
  3. Мы сохраняем это новое изображение, указав путь.

Лос -Анджелес – это не Лос -Анджелес, а режим, указанный PIL в их документации.

L -  (8-bit pixels, black, and white)
LA (L with alpha)

Фотография сделана из Google, обновлена мной

2. Разделение цветного изображения на их канал

Здесь цветное изображение имеет 3 слоя, как упоминалось ранее: красный, зеленый и синий. То, что мы сделаем, это извлечь каждый канал отдельно от изображения и сохранить эти отдельные каналы. Простой!!

from PIL import Image
img = Image.open('images/sunset.png')
data = img.getdata()

Кредиты с картинками: Google

Здесь мы открываем изображение и назначаем его переменной IMG. После этого мы извлекаем данные цветного изображения. Мы также упоминали ранее, что канал изображения образуется через матрицу, которая охватывает значения пикселей в диапазоне от 0 до 255.

Теперь для одного канала у нас есть одна матрица, заполненная значениями пикселей. Но на цветном изображении у нас есть 3 канала (красный, зеленый и синий), поэтому у нас есть три матрицы, заполненные значением пикселя.

Опять же, матрица представлена в двухмерном массиве с рядами и столбцами. Теперь мы должны включить значения 3 матриц, поэтому мы делаем это с помощью трехмерного массива, и это входит в этот формат.

[[
  [r(0,0), g(0,0), b(0,0)], [r(0,1), g(0,1), b(0,1)]], 
  [[r(1,0), g(1,0), b(1,0)], [r(1,1), g(1,1), b(1,1)]
]] 

Этот формат лучше понят схематически, как показано:

Таким образом, данные, которые мы извлекаем из изображения, будут из формата:

[[[202 112 104]
 [202 112 104]
 [202 112 104]
 ...
 [200 111 105]
 [200 111 105]
 [199 110 104]]

 [[202 112 104]
 [202 112 104]
 [202 112 104]
 ...
 [200 111 103]
 [200 111 103]
 [199 110 102]]]

Давайте использовать эти данные и разделить эти данные, чтобы мы могли получить значения R Pixel для красного канала, значения пикселей G для зеленого канала и значения B пикселя для синего канала.

red = [(pixel[0], 0, 0) for pixel in data]
green = [(0, pixel[1], 0) for pixel in data]
blue = [(0, 0, pixel[2]) for pixel in data]

Как мы видели, данные имеют трехмерный формат массива, поэтому давайте сосредоточимся на извлечении только красной матрицы на данный момент. В трехмерном массиве внутренний массив имеет формат [r, g, b] И нам нужно взять первое значение этого массива, чтобы получить значения красного пикселя. Мы делаем это аналогичным образом для создания зеленой матрицы и синей матрицы.

Давайте использовать эти 3 матрицы и сохранить их. Затем мы можем увидеть отдельные красные, зеленые и синие каналы исходного изображения.

img.putdata(red)
img.save('images/red_sunset.png')
img.putdata(blue)
img.save('images/blue_sunset.png')
img.putdata(green)
img.save('images/green_sunset.png')

Здесь мы используем putdata () Встроенная функция для копирования содержимого матрицы в исходное изображение, а затем сохранить его.

Обработка изображений – за принципами сцены

Для таких методов обработки изображений, как изменение/изменение размера и вращение, формируются на основе принципов ближайшего соседа, билинейные преобразования и другие принципы, которые я объясню подробно.

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

1. Принцип ближайшего соседа

В этом принципе у нас есть исходное изображение (а), и мы применяем метод обработки изображений для преобразования его в модифицированное изображение (b).

Я объясню это, изменяя размер изображения с (3×3) на B (9×9). Первый шаг, который нужно сделать, – это сделать координаты изображения, множественную его на 3, затем мы получим координату на изображении B. Эта новая координата изображения B будет иметь то же значение пикселя, что и исходная координата на изображении A.

A(0, 0) => 110
A(0, 1) => 120  
>>> x3 <<<
B(0, 0) => 110
B(0, 3) => 120 

Теперь нам нужно найти значение пикселя B (0, 1), и для этого мы делаем, как следуем:

B(0, 1) => ? 
>>> /3 <<< 
A(0, 1/3) => no such coordinate exists, right?

Вы правы, такая координата не существует, но ближайший сосед спрашивает, что это A (0, 1/3) ближе к A (0, 0) или A (0, 1) Анкет Здесь он ближе к A (0, 1) Таким образом, значение пикселя B (0, 1) будет таким же, как A (0, 0) . Точно так же рассчитываются другие координаты! Это не так эффективно, конечно!

2. Билинейная интерполяция

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

Давайте возьмем пример изменения размера изображения A (3×3) на изображение B (9×9).

Прежде чем мы поймем билинейную трансформацию, нам нужно понять линейное преобразование. Мы возьмем тот же пример, что и у ближайшего соседа. Итак, нам нужно найти B (0, 1) И то, как мы это делаем, найдено A (0, 1/3) И способ, которым мы делаем это:

У нас есть значение пикселя A (0, 0) и A (0, 1) Итак, сначала мы находим 1/3 * значение @ A (0, 1) и 2/3 * Значение @ A (0, 0) . Добавьте их вверх и вокруг этого, вы получили значение пикселя для A (0, 1/3) И это ваша ценность для B (0, 1) Анкет

Мы используем этот метод, чтобы найти любую координату между 2 данными координатами. В Bilinear мы используем 4 последовательных координат на исходном изображении A. С этими координатами мы рассчитываем идеальную координату на изображении A и масштабируйте его до координаты в изображении B.

  1. У нас есть значения пикселей A (0, 0) , A (0, 1) , A (1, 0) и A (1, 1) Анкет Сначала мы находим координаты квадратных блоков между 2 координатами изображения A Использует метод линейной интерполяции.
  2. С координатами 2 квадратных блоков мы можем интерполировать и найти координату блока треугольника (выбранный!).

Как только мы найдем координату блока треугольника, мы просто сопоставляем его с изображением B.

Так что это основная идея о том, как работает билинеар. Таким образом, мы можем найти любую координату между 2 координатами на нашем изображении B. С помощью этого принципа мы можем получить гораздо точные значения пикселей и более плавное модифицированное изображение.

3. Бикубическая интерполяция

В бикубической интерполяции мы используем кубическое уравнение. Однако, как я уже упоминал ранее, мы сосредоточимся на теоретическом, а не на математическом понимании принципа.

Давайте посмотрим на линейную/билинейную интерполяцию, чтобы преобразовать из изображения A в изображение B.

Приведенная ниже диаграмма в 2-D плоскости показывает, что b/w Любая 2 заданная координата-это просто линия, и вы можете найти любую координату между этими 2, используя метод линейной интерполяции:

Тем не менее, эта линейная интерполяция не всегда обеспечивает высокий точный или плавный результат. Таким образом, мы используем бикубический.

На этой диаграмме, если я использую метод BICUBIC, он подразумевает, что если есть 2 заданные координаты, и есть линия, соединяющая эти 2, то мы будем использовать касательную/производную в этих 2 координатах, сделаем кривую и найдем координату между этими 2.

Как мы рассчитываем производные в координатах?

Для расчета касательной в этих 2 данных координатах нам также нужны соседние координаты этих 2! Так легко, верно?

Мы используем метод линейной интерполяции для расчета идеальной координаты в билинейной интерполяции с использованием 4 координат.

Если мы хотим найти идеальную координату между этими 4 с использованием Bicubic, нам нужно использовать расширение, как показано на диаграмме.

Для Bicubic мы сделаем это так, как следует:

  1. Для каждой строки мы найдем координату (квадратные блоки) между 2 данными координатами, и нам нужно найти касательную в этих 2 данных координатах, используя соседка данного 2.
  2. Как только координаты квадратных блоков рассчитаны, мы используем тот же метод в 1 и получаем идеальную координату блока треугольника.

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

Давайте рассмотрим наш последний принцип, прежде чем мы перейдем к реализации с помощью PIL.

4. Метод свертки

Это Важно принцип! Это важно, чтобы «сегодня принципы», такие как би-кубический, билинеар, основан на самом принципе свертки.

Давайте начнем с понимания свертки. В свертке, скажем, у нас есть изображение I (7×7), и мы здесь сделаем, так это то, что укротите окно ядра k (3×3) по изображению I такого, что мы получим новое изображение (7×7) * k (3×3)

Кредиты с картинками: Google

На диаграмме мы видим, что ядро К скользит Изображение I. Затем, когда ядро k превышает раздел изображения I, он умножает значения пикселей K и I, а затем добавляет их все в разделе, и мы получаем свернутое значение пикселя изображения. Я знаю, что это звучит сбивает с толку, поэтому мы поймем это с примером.

На этом изображении у нас есть раздел изображения I И у нас есть наше ядро К. с диаграммы, понятно, как 9-пиксельные значения приводят к 1 запутанному значению пикселя. Таким образом, мы продолжаем сдвигать ядро K по всему изображению I и получаем запутанное изображение J (I * k).

Это тяжелый процесс, не позволяйте никому говорить вам по -другому!

Прежде чем двигаться дальше, я хотел бы уточнить, что эти методы, которые я указал, используются в качестве фильтров для выполнения преобразования на изображениях.

Реализация преобразования с помощью простого PIL

Согласно документации PIL:

Методы изменения размера изображения resize () а также Миниатюра () Возьмите аргумент о повторном примере, который сообщает, какой фильтр следует использовать для повторной выборки. Возможные значения Pil.image. Ближайший , Pil.image. Билинеар , Pil.image. Бикубик а также Pil.image. Antialias .

~

Высокопроизводительные характеристики фильтра Lanczos остались прежними. Для билинейного фильтра он улучшился в 1,5 раза, а для бикубика в четыре раза.

Из этих двух контекстов из документации мы знаем, что такое ближайший, билинейный и бикубический, так что это круто! Что такое Antialias и Lanczos? Antialias-это высококачественный фильтр, основанный на свертках (мы узнали об этом!). Теперь фильтр Antilias – это всего лишь псевдоним Lanczos. Таким образом, Lanczos и Antialias основаны на свертке.

Давайте реализуем изменение размера с использованием этих фильтров с помощью PIL.

В документации, для использования фильтров при изменении размера и вращения мы можем явно использовать их имена или назначенный им номер.

NEAREST = NONE = 0
BILINEAR = LINEAR = 2
BICUBIC = CUBIC = 3
LANCZOS = ANTIALIAS = 1

1. Изменение размера изображения с использованием разных фильтров

Мы собираемся повторно использовать закат солнца Изображение, которое мы делали, разделяя изображение на разные каналы. Получим кодирование!

from PIL import Image
img = Image.open('images/sunset.png')
size = (350, 550)
nearest_resize = img.resize(size, 0)
lanczos_resize = img.resize(size, 1)
bilinear_resize = img.resize(size, 2)
bicubic_resize = img.resize(size, 3)

nearest_resize.save('images/nearest_sunset.png')
lanczos_resize.save('images/lanczos_sunset.png')
bilinear_resize.save('images/bilinear_sunset.png')
bicubic_resize.save('images/bicubic_sunset.png') 

Здесь мы изменяем размер исходного изображения, используя разные фильтры. С текущим изображением вы, возможно, не сможете увидеть большую разницу, как показано.

Тем не менее, это конкретное изображение обеспечивает хорошую разницу между изменением размера между различными фильтрами. Я бы предложил посмотреть на фильтры, которые использовались нами в этом блоге, и наблюдать за разницей.

2. Вращение изображения с использованием разных фильтров

Мы будем использовать фильтры, чтобы повернуть изображение в любой степени, которую мы хотим. Тем не менее, есть проблема, когда, скажем, 30 или 45 градусов, края обрезаются. Если мы не хотим, чтобы мы настраивались развернуть = true что предотвратит это!

В изменении размера мы использовали числа, чтобы изобразить, какой фильтр мы хотим использовать за изображением при изменении размера. Здесь мы явно введем их имена и снова будем использовать то же самое закат изображение.

from PIL import Image
img = Image.open('images/sunset.png')

nearest_rotate = img.rotate(45, resample=Image.NEAREST, expand=True)
bilinear_rotate = img.rotate(45, resample=Image.BILINEAR, expand=True)
bicubic_rotate = img.rotate(45, resample=Image.BICUBIC, expand=True)

nearest_rotate.save('images/nearest_rotate_sunset.png')
bilinear_rotate.save('images/bilinear_rotate_sunset.png')
bicubic_rotate.save('images/bicubic_rotate_sunset.png') 

Здесь Lanczos Фильтр не может быть использован для вращения, так как он не реализован самим PIL и довольно тяжелым процессом, поэтому не имеет никакого преимущества по сравнению с Бикубик на данный момент.

PIL не ограничивается просто изменением размера, ротации, разделения изображений, но это может сделать гораздо больше. Все, что вы выполняете на инструментах редактирования фотографий, таких как Crop, Popy-Pasty, слияние 2 изображений, может быть достигнуто через PIL всего через несколько строк кода. В этом я только использовал Изображение модуль Но есть много модулей для самого пила.

Для любых дополнительных ресурсов для PIL просто просмотрите их Документация И, конечно, если застрять, переполнение стека всегда дает каждый ответ. PIL является эффективной библиотекой, и я освещал 2 наиболее часто используемых операциях и принципах, которые находятся за трансформацией.

Источники для каждого кода присутствуют на GitHub Также, так что вы можете обратиться оттуда и код рядом!

Если возникают какие -либо вопросы относительно PIL или что -либо, упомянутое в статье, не стесняйтесь упоминать об этом в комментариях! До этого прощай. 👋

Оригинал: “https://dev.to/devunf/getting-familiarized-with-image-processing-its-implementation-using-pil-2j9a”