
МТ5
.docxГУАП
КАФЕДРА № 41
ОТЧЕТ ЗАЩИЩЕН С ОЦЕНКОЙ
ПРЕПОДАВАТЕЛЬ
доцент, канд. техн. наук, доцент |
|
|
|
О.О. Жаринов |
должность, уч. степень, звание |
|
подпись, дата |
|
инициалы, фамилия |
ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ №5
|
Изучение методов управления контрастностью изображений
|
по курсу: МУЛЬТИМЕДИА ТЕХНОЛОГИИ |
|
|
РАБОТУ ВЫПОЛНИЛ
СТУДЕНТ гр. № |
|
|
|
|
|
|
|
|
подпись, дата |
|
инициалы, фамилия |
Санкт-Петербург 2025
Цель работы: изучить методологию управления контрастностью изображений с целью улучшения их визуального восприятия. Реализовать типовые методы контрастирования изображений на языке Python.
Вариант 13:
На рисунке 1 представлен вариант задания.
Рисунок 1 – Вариант задания
Краткие теоретические сведения о цифровых изображениях и методах улучшения их визуальных характеристик:
Для обработки изображений в составе Python имеется ряд библиотек, из которых наиболее популярными являются OpenCV (cv2), scikit-image (skimage), PIL/Pillow, Mahotas [1].
Всегда актуальной задачей обработки изображений является изменение яркости и контрастности [2]. Управление яркостью и контрастностью обычно производится после анализа статистических характеристик обрабатываемого изображения. Для проведения такого анализа в библиотечных модулях Python имеются специализированные методы и функции.
Одной из основных статистических характеристик черно-белого (синонимы: полутонового, монохромного) изображения является гистограмма распределения яркостей элементов изображения, которую можно вычислять как для всего изображения целиком, так и локально.
Для построения общей гистограммы полутонового изображения используется, как правило, 256 уровней яркости (интенсивности) изображения (ширина интервалов гистограммы равна 1), а высота каждого столбца – это количество пикселей изображения соответствующей яркости (интенсивности). Получать данные для построения гистограммы в Python можно как посредством стандартных методов, так и посредством прямого расчета (см. пример в [3]). Еще нужно понимать, что при использовании некоторых методов при открытии изображения в Python происходит автоматическая нормализация данных, при которой диапазон исходных значений от 0 до 255 (данные типа uint8) линейно преобразовывается в диапазон от 0 до 1 (данные типа float32), хотя можно открывать изображения и без нормировки (см. [4]). В любом случае для промежуточных вычислений при обработке изображений все равно следует преобразовывать данные в формат float32 или даже float64, чтобы избежать вычислительных погрешностей.
С целью повышения контраста изображений, на которых мелкие детали на темных и светлых участках плохо различимы, и/или сами изображения характеризуются низким контрастом, используют методы обработки изображений, когда величина яркости, соответствующая каждому пикселю, изменяется так, чтобы гистограмма изображения после обработки приобретала бы заданные свойства. Оптимальным с точки зрения зрительного восприятия человеком является изображение, элементы которого имеют равномерное распределение яркостей.
Улучшенные изображения получают путем выравнивания (эквализации) гистограммы, то есть, согласованно изменяя величины яркостей всех пикселей стремятся достичь равномерности гистограммы обработанного изображения.
Данный метод преобразования может быть глобальным, когда используется информация обо всем изображении и получается общий для всех пикселей закон преобразования, и неглобальным, когда для преобразования яркостей пикселей используются характеристики, полученные для локальных областей изображения, и выравниваются гистограммы отдельных участков. Такой локальный (его еще называют адаптивным) подход к обработке бывает эффективным в случаях, когда контрастность на разных участках изображения существенно неодинакова, в результате чего некоторые низкоконтрастные детали могут не “проявиться” при глобальном методе обработки. Существует также ряд других методов видоизменения гистограммы, которые приводят к получению изображений с заранее заданным распределением яркостей пикселей, с целью не только улучшения качества изображения, а для создания визуальных спецэффектов.
Метод exposure.adjust_sigmoid используется для нелинейного преобразования яркости изображения с помощью сигмоидальной функции. Этот метод часто применяется для улучшения контраста изображения, особенно в областях с низкой или высокой яркостью. Метод имеет следующие параметры: image, cutoff, gain, inv [7].
Преобразование яркости пикселя I(x,y) выполняется по формуле:
(1)
где:
I(x,y) — исходное значение яркости пикселя (нормализованное в диапазоне [0, 1]).
Iout(x,y) — преобразованное значение яркости.
C — параметр cutoff, определяющий точку перегиба сигмоиды (по умолчанию 0.5).
G — параметр gain, управляющий крутизной сигмоиды.
Метод имеет следующие параметры: image – входной изображение, cutoff – C в формуле (1) , gain – G в формуле (1), inv — логический параметр, определяющий, инвертировать ли сигмоиду (по умолчанию False).
Параметр G (gain) определяет крутизну сигмоидальной кривой. Чем больше значение G, тем более резким будет переход между темными и светлыми областями изображения.
Ход работы:
Для выполнения лабораторной работы было выбрано очень затемнённое изображение (Рисунок 2, 3).
Рисунок 2 – Выбранное изображение
Рисунок 3 – Гистограмма яркости выбранного изображения
Была разработана программа для обработки цветного изображения с применением преобразования в цветовое пространство LAB, нормализации яркости и визуализации результатов (Листинг 1).
На первом этапе программа загружает исходное изображение в формате RGB и преобразует его в цветовое пространство LAB с использованием функции rgb2lab из библиотеки skimage. Из полученного изображения выделяется канал яркости (L-канал), который нормируется путем деления на 100 для приведения значений к диапазону [0,1].
Для улучшения контрастности яркостной компоненты применяется метод линейной растяжки интенсивности с помощью функции rescale_intensity из модуля skimage.exposure. Значения входного диапазона определяются минимальными и максимальными значениями яркости изображения, а выходной диапазон устанавливается в пределах от 0.1 до 0.9. Это позволяет избежать крайних значений и улучшить визуальное восприятие изображения.
После обработки канал яркости заменяется на нормализованный, и изображение переводится обратно в пространство RGB с использованием функции lab2rgb. В результате получается изображение с улучшенной яркостью и контрастом.
Для анализа распределения яркости в обработанном изображении строится гистограмма, отражающая количество пикселей для каждого уровня серого в диапазоне [0,1]. Гистограмма отображается с использованием библиотеки matplotlib, а также применяется экспоненциальный формат для оси Y.
Итоговое изображение с улучшенной яркостью сохраняется в файл в формате jpg с качеством 100%. Для сохранения используется функция imsave из библиотеки skimage.io.
Листинг 1 – Применение rescale_intensity
import numpy as np
import matplotlib.pyplot as plt
from skimage import io, color, exposure
from skimage.color import rgb2lab, lab2rgb
image_path = "input_image.jpg"
image = io.imread(image_path) # считано изо
LAB_image = rgb2lab(image) # в пр-во LAB
L = LAB_image[:, :, 0] / 100 # выделяем матрицу яркости
plt.imshow(image) # отобразили изо
plt.axis("off")
plt.show()
# -----------------------------------------------------
# применим метод .rescale_intensity:
low, high = np.min(L), np.max(L)
bottom, top = 0.1, 0.9
L_out = exposure.rescale_intensity(
L, in_range=(low, high), out_range=(bottom, top)
).astype(np.float32)
# -----------------------------------------------------
LAB_image[:, :, 0] = L_out * 100 # заменили матрицу яркости
image_out = lab2rgb(LAB_image) # вернули цвет в изображение
plt.imshow(image_out) # отобразили изо после обработки
plt.axis("off")
plt.show()
# рассчитали данные гистограммы:
histogram, bin_edges = np.histogram(image_out, bins=256, range=(0, 1))
# выводим график гистограммы:
fig, ax = plt.subplots(figsize=(5, 4))
plt.ticklabel_format(axis="y", style="sci", scilimits=(4, 4))
ax.set_xlim(0, 1)
ax.grid(True)
ax.set_title("Grayscale Histogram")
ax.set_xlabel("grayscale value")
ax.set_ylabel("pixel count")
ax.bar(bin_edges[0:-1], histogram, width=1 / 128)
plt.show()
# сохраним обработанное изображение в файл:
image_out = (255 * image_out).astype(np.uint8)
io.imsave("2rescale.jpg", image_out, quality=100)
На рисунке 4 представлен результат применения rescale_intensity. Метод восстановил некоторые детали, но при этом всё изображение стало “блёклым”, что является следствием работы метода по всему изображению, а не только проблемным участкам. На рисунке 5 представлена гистограмма яркости.
Рисунок 4 – Результат применения rescale_intensity
Рисунок 5 – Гистограмма яркости
К изображению был применен метод adjust_gamma с параметром gamma=0.6 (Листинг 2). Благодаря этому методу удалось восстановить детали и не испортить изображение там, где их было достаточно, но в некоторых высветленных местах заметны резкие переходы цвета, что может быть свидетельством низкого разрешения изображения (Рисунок 6, 7).
Листинг 2 – Применение метода adjust_gamma
import numpy as np
import matplotlib.pyplot as plt
from skimage import io, color, exposure
from skimage.color import rgb2lab, lab2rgb
image_path = "input_image.jpg"
image = io.imread(image_path) # считано изо
LAB_image = rgb2lab(image) # в пр-во LAB
L = LAB_image[:, :, 0] / 100 # выделяем матрицу яркости
plt.imshow(image) # отобразили изо
plt.axis("off")
plt.show()
L_out = exposure.adjust_gamma(L, gamma=0.6)
LAB_image[:, :, 0] = L_out * 100 # заменили матрицу яркости
image_out = lab2rgb(LAB_image) # вернули цвет в изображение
plt.imshow(image_out) # отобразили изо после обработки
plt.axis("off")
plt.show()
# рассчитали данные гистограммы:
histogram, bin_edges = np.histogram(image_out, bins=256, range=(0, 1))
# выводим график гистограммы:
fig, ax = plt.subplots(figsize=(5, 4))
plt.ticklabel_format(axis="y", style="sci", scilimits=(4, 4))
ax.set_xlim(0, 1)
ax.grid(True)
ax.set_title("Grayscale Histogram")
ax.set_xlabel("grayscale value")
ax.set_ylabel("pixel count")
ax.bar(bin_edges[0:-1], histogram, width=1 / 128)
plt.show()
# сохраним обработанное изображение в файл:
image_out = (255 * image_out).astype(np.uint8)
io.imsave("3gamma.jpg", image_out, quality=100)
Рисунок 6 – Результат применения adjust_gamma
Рисунок 7 – Гистограмма яркости
При слишком низком значении параметра, на изображении четко выделяются полностью черные участки, а остальные сливаются в один цвет. На рисунке 8 представлен результат с параметром gamma=0.1.
Рисунок 8 – Изображение с слишком низким значением gamma
Был применен метод equalize_hist с параметром nbins=128 (Листинг 3). Получившееся изображение в сравненнии с оригинальным имеет больше деталей в тёмных участках, но было полностью высветлено (Рисунок 9, 10).
Листинг 3 – Применение метода equalize_hist
L_out = exposure.equalize_hist(L, nbins=128)
Рисунок 9 – Результат применения equalize_hist
Рисунок 10 – Гистограмма яркости
Был применен метод equalize_adapthist с параметрами kernel_size=(8, 8), clip_limit=0.1, nbins=128 (Листинг 4). Результат позволяет рассмотреть больше деталей на дороге и домах, но также возросла резкость всего изображения, что ухудшило визуальное восприятие (Рисунок 11, 12).
Листинг 4 – Применение метода equalize_adapthist
L_out = exposure.equalize_adapthist(L, kernel_size=(8, 8), clip_limit=0.1, nbins=128)
Рисунок 11 – Применение метода equalize_adapthist
Рисунок 12 – Гистограмма яркости
Был применен метод по варианту adjust_sigmoid (Листинг 5) cо стандартными значениями параметров cutoff=0.5, inf=F и значениями gain равными: 10, 0, -10, 4 (Рисунок 13).
При gain = 10 изображение стало ещё темнее, потеряно очень много деталей.
При gain = 0 изображение стало полностью залито серым цветом, что подтверждается гистограммой яркости.
При gain = -10 тёмные участки стали высветлены, а светлые – затемнены.
Листинг 5 – Применение adjust_sigmoid
L_out = exposure.adjust_sigmoid(L, cutoff=0.5, gain=10)
Рисунок 13 – Результаты обработки adjust_sigmoid с различным значением gain
При gain = 4 удалось получить наиболее приемлимый вариант изображения при стандартных значениях других параметров (Рисунок 14, 15).
Рисунок 14 – Изображение при gain=4
Рисунок 15 – Гистограмма яркости при gain=4
Вывод: в ходе выполнения лабораторной работы была изучена методология управления контрастностью изображений с целью улучшения их визуального восприятия, реализованы типовые методы контрастирования изображений на языке Python. Использовались следующие методы: rescale_intensity, adjust_gamma, equalize_hist, equalize_adapthist, adjust_sigmoid. Наилучший результат удалось получить при использовании adjust_gamma, были восстановлены детали без сильных пересветов, остальные методы предоставили либо слишком тёмное, либо слишком светлое изображение.
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
10 инструментов Python для работы с изображениями URL: https://dzen.ru/a/XoS_XuNmhR6wjdJC
Основы цифровой обработки изображений: учеб. Пособие / Жаринов О.О. СПб: ГУАП. 2023. – 122 с.
How to plot the histogram of an image in Python // URL: https://www.educative.io/answers/how-to-plot-the-histogram-of-an-imagein-python
Creating Histograms // URL: https://bear-rsg.github.io/imageprocessing/instructor/05-creating-histograms.html
Документация по skimage.exposure (на англ. яз.) // URL: https://scikitimage.org/docs/stable/api/skimage.exposure.html
Жаринов О.О. Учебно-методические материалы к выполнению лабораторной работы №5 по дисциплине “Мультимедиа-технологии”, гр.4116,4117, 4018. ГУАП, 2025. – 12 с. (Интернет-ресурс) // URL: https://pro.guap.ru/inside/student/tasks/9457fc8043c1e8c891a195a7acda4d3a/download
Документация по skimage.exposure.adjust_sigmoid (на англ. яз.) // URL: https://scikit-image.org/docs/stable/api/skimage.exposure.html#skimage.exposure.adjust_sigmoid