Лабораторная работа №7 Оцифровка изображений в Python
Технические требования:
Среда разработки для написания кода на Python Компилятор Python 3 (+ стандартный набор библиотек)
Требования к знаниям студентов:
Основы синтаксиса Python 3:
-умение работать с переменными и знание типов данных
-умение работать со списками
-умение считывать данные из файла
-умение выводить данные в консоль/файл
-знание условных конструкций if-elif-else
-умение писать циклы for/while
-умение создавать и вызывать функции, возращать значения
Цель работы:
Знакомство с численными методами для решения задач: - оцифровка изображений jpg/png
Теоретическое введение:
Блок 1 “Оцифровка изображений
При работе с цифровыми изображениями часто возникает задача анализа и манипуляции отдельными пикселями. Это особенно важно, когда речь идет о распознании объектов, изменении цветов или обработке изображений на уровне отдельных элементов. В качестве наиболее актуальных реальных задач можно привести обнаружение лиц (поиск лица основывается на выделении участков с характерными оттенками кожи и контрастностью), анализ дефектов на производстве (автоматическое выявление трещин, царапин или других повреждений на фотографиях деталей оборудования), изменение палитры (создание эффектов постобработки (чёрно-белого эффекта, сепия-фильтра и т.п.)). Одним из основных инструментов для такой работы является библиотека Pillow.
Для примера рассмотрим 2 часто используемых формата изображений: JPG и PNG. JPG спользуется для хранения фотографических изображений, сжимается с потерями (lossy compression), сохраняет яркие визуальные данные, но немного ухудшая качество изображения. Поддерживает глубину цвета RGB (8 бит/цвет). PNG используется преимущественно для веб-графики и иконок, поддерживает
прозрачность альфа-канала, сжатие без потерь (lossless compression), подходит для чётких контуров и логотипов.
Загрузка изображения и получение пиксельных данных
Начнём с загрузки изображения и получения значения RGB конкретного пикселя. Допустим, у вас есть изображение формата JPG или PNG, сохранённое в файле под названием image.jpg:
from PIL import Image
#Открываем изображение img = Image.open('image.jpg')
#Получаем размеры изображения width, height = img.size
#Извлекаем значение RGB пикселя (x,y) pixel_color = img.getpixel((x, y))
print(f'Цвет пикселя ({x}, {y}) равен {pixel_color}')
Пример вывода:
Цвет пикселя (100, 150) равен (170, 120, 80)
Значения представляют собой три канала: красный (R), зелёный (G) и синий (B), каждый из которых представлен числом от 0 до 255.
Разбор всех пикселей изображения
Чтобы перебрать все пиксели изображения и проанализировать их, можно воспользоваться циклом:
for x in range(width): for y in range(height):
pixel_value = img.getpixel((x, y))
print(f"Пиксель ({x},{y}): R={pixel_value[0]}, G={pixel_value[1]}, B={pixel_value[2]}")
Это простой цикл, который выводит координату каждого пикселя вместе с его значением RGB. Однако будьте осторожны: обработка больших изображений таким образом может занять значительное количество времени.
Манипуляции с цветами
Давайте попробуем применить простую операцию к каждому пикселю, например, увеличить яркость изображения путём умножения каждого компонента RGB на коэффициент:
def increase_brightness(pixel, factor):
return tuple(int(channel * factor) for channel in pixel[:3])
new_img = Image.new(img.mode, img.size)
for x in range(width): for y in range(height):
old_pixel = img.getpixel((x, y))
new_pixel = increase_brightness(old_pixel, 1.5) new_img.putpixel((x, y), new_pixel)
new_img.show()
Этот код создаёт новую копию изображения, увеличивая яркость каждого пикселя в полтора раза.
Работа с матрицами пикселей (NumPy)
Если вам нужен быстрый доступ ко всему массиву пикселей одновременно, можно использовать библиотеку NumPy, которая эффективно работает с большими массивами данных.
import numpy as np
np_array = np.array(img)
# Теперь np_array представляет собой трёхмерный массив:
#Ширина × Высота × Каналы(RGBA)
#Доступ к первому пикселю (левый верхний угол): first_pixel_rgb = np_array[0][0]
#Вывод первых пяти строк первого столбца (получаем вертикальную линию пикселей):
vertical_line = np_array[:, 0][:5]
print(first_pixel_rgb) print(vertical_line)
Использование NumPy значительно ускоряет обработку крупных изображений благодаря векторизации вычислений.
Анализ распределения цветов
Можно построить гистограмму распределения цветов в изображении. Это позволит визуально оценить преобладающие оттенки.
histogram = img.histogram()
# Отображение гистограммы с помощью matplotlib import matplotlib.pyplot as plt
plt.figure(figsize=(10, 5))
plt.bar(range(len(histogram)), histogram, color='b', width=1) plt.title('Распределение цветов в изображении') plt.xlabel('Значение оттенка')
plt.ylabel('Количество пикселей') plt.show()
Эта простая диаграмма показывает распределение оттенков в изображении.
Практическая часть
Студентам предлагается в обязательном порядке выполнить задания 1.1 и 1.2 с произвольно выбранными изображениями, а также, по указанию преподавателя, выполнить задание 1.3.
Задание 1.1 (основная часть) “Изменение яркости изображения”
Напишите программу, которая уменьшает или увеличивает яркость изображения.
Задание 1.2 (основная часть) “Замена цветов в изображении”
Придумайте критерий того, что пиксель является белым (или условно белым). Напишите программу, которая заменяет все белые (условно белые) пиксели изображения на пиксели другого цвета.
Задание 1.3 (дополнительная часть) “Творческое задание”
Напишите программу, которая реализует различные действия с изображением (считает число “ярких” точек, вычисляет процент белых пикселей на всем изображении и т.д.). Одельно опишите функционал вашей программы. Подумайте, для каких целей она [программа] может быть полезной.
Заключение:
В качестве результата необходимо представить отчет, включающий в себя листинг программы (текст исходного кода), полученные результаты, а также их анализ.
При сдаче работы студент должен знать изученные численные методы, а также разбираться в коде написанной программы.
