Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

7

.pdf
Скачиваний:
0
Добавлен:
16.05.2025
Размер:
1.33 Mб
Скачать

МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ

федеральное государственное автономное образовательное учреждение высшего образования

«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ АЭРОКОСМИЧЕСКОГО ПРИБОРОСТРОЕНИЯ»

Кафедра 41

ПРЕПОДАВАТЕЛЬ

 

 

 

 

 

доц., к.т.н., доц.

 

 

 

О. О. Жаринов

 

 

 

 

 

 

 

должность, уч. степень, звание

 

подпись, дата

 

инициалы, фамилия

Лабораторная работа №7

Основы цифровой фильтрации изображений. Пространственные фильтры

по курсу: Мультимедиа технологии

СТУДЕНТКА ГР. № Z0411

07.04.25

 

М. В. Карелина

 

 

 

 

 

 

 

номер группы

 

подпись, дата

 

инициалы, фамилия

Номер студенческого билета: 2020/3477

Санкт-Петербург

2025

Цель работы:

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

Вариант 7.

Вариант №2 с неравномерным смазом: столбец в центре маски представляет собой последовательность линейно возрастающих значений.

В данной работе рассматриваются методы восстановления изображений, искажённых смазыванием (размытиями), с использованием двух известных алгоритмов: фильтра Винера и метода Люси-Ричардсон. Целью является оценка эффективности восстановления изображений в различных условиях, включая:

-точное знание маски смазывания (PSF);

-ошибки в модели PSF (неправильная маска);

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

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

Метод Люси-Ричардсон — это итеративный алгоритм, основанный на вероятностной модели (по Байесу), который особенно эффективен при наличии размытости и шума, но требует знания PSF и определения числа итераций.

Для начала рассмотрим код представленный в листинге 1, выполняющий обработку изображения с использованием цветовой модели LAB для улучшения его яркости. Сначала изображение загружается и преобразуется из модели BGR в LAB. Затем извлекается и нормируется канал яркости. Далее создаётся маска пространственного фильтра (PSF), которая

применяется к матрице яркости для фильтрации. После этого обрабатываются значения яркости, чтобы избежать отрицательных значений, и изменённые данные возвращаются в LAB-изображение. Затем LAB-изображение преобразуется обратно в модель BGR. На рисунке 1 представлено оригинальное изображение которое в дальнейшем подверглось размытию через приложение-редактор. На рисунках 2 и 3 результат выполнения программы.

Листинг 1. Программа, реализующая один из вариантов универсального метода

повышения резкости расфокусированного изображения

import cv2

import numpy as np

import matplotlib.pyplot as plt

#Чтение исходного изображения input_image = cv2.imread('LR7.jpg')

#Преобразование изображения из цветовой модели BGR в LAB

LAB_image = cv2.cvtColor(input_image, cv2.COLOR_BGR2LAB)

#Извлечение матрицы яркости (канал L) из LAB-изображения и нормировка значений

L = LAB_image[:, :, 0] / 100 # Значения канала L находятся в диапазоне от 0

до 100

#Задаем маску (PSF - функцию пространственного фильтра) для фильтрации

c = 0.60 # Параметр, который можно настраивать для изменения фильтрующего эффекта

PSF = np.array([

[-c, -c, -c], # Соседние пиксели в горизонтальном и вертикальном направлениях

[-c, 1 + 8 * c, -c], # Центральный пиксель с весом, увеличенным на 8*c [-c, -c, -c] # Соседние пиксели в горизонтальном и вертикальном

направлениях

])

#Применяем фильтрацию к матрице яркости L с использованием заданной маски

PSF

L_out = cv2.filter2D(L, -1, PSF)

#Обработка яркости, чтобы избежать отрицательных значений

L_max = np.max(L_out) # Находим максимальное значение яркости после фильтрации

L_out = np.clip(L_out, a_min=0., a_max=L_max) # Обрезаем значения, чтобы избежать искажений

# Заменяем изменённую матрицу яркости обратно в LAB-изображение LAB_image[:, :, 0] = L_out * 100 # Умножаем на 100, чтобы вернуть значения в диапазон от 0 до 100

#Преобразование LAB-изображения обратно в цветовую модель BGR image_out = cv2.cvtColor(LAB_image, cv2.COLOR_LAB2BGR)

#Визуализация исходного и обработанного изображений

plt.figure(figsize=(10, 5))

 

# Отображение исходного изображения

 

plt.subplot(1, 2, 1)

 

plt.imshow(cv2.cvtColor(input_image, cv2.COLOR_BGR2RGB))

# Преобразуем BGR

в RGB для корректного отображения

 

plt.title('Исходное изображение')

 

plt.axis('off')

# Убираем оси

 

# Отображение обработанного изображения

 

plt.subplot(1, 2, 2)

 

plt.imshow(cv2.cvtColor(image_out, cv2.COLOR_BGR2RGB))

# Преобразуем BGR в

RGB для корректного отображения

 

plt.title('Обработанное изображение')

 

plt.axis('off')

# Убираем оси

 

plt.tight_layout() # Убираем лишние пробелы между подграфиками plt.show() # Показываем график

# Сохранение обработанного изображения cv2.imwrite('LR7.1.jpg', image_out)

Рисунок 1 - Оригинальное изображение

Рисунок 2 - Результат обработки универсальным методом повышения резкости

Теперь перейдём к обработке изображения с использованием методов Люси-Ричардсона и Винера. (Листинг 2)

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

35 градусов. После чего нанесём размытие на изображение, используя функцию свёртки cv2.filter2D, применив к нему созданную маску. Результат обработке на рисунке 3.

Листинг 2. Реализация методов восстановления изображения с помощью фильтра

Винера и Люси-Ричардсона

import cv2

from skimage import restoration import numpy as np

import matplotlib.pyplot as plt

#Функция, создающая смаз:

#size - размер размаза в пикселях,

#angle - направление смаза, в градусах def blur_mask(size, angle):

k = np.zeros((size, size), dtype=np.float32)

k[(size - 1) // 2, :] = np.ones(size, dtype=np.float32)

k = cv2.warpAffine(k, cv2.getRotationMatrix2D((size / 2 - 0.5, size / 2 - 0.5), angle, 1.0), (size, size))

k = k / np.sum(k) # нормировка return k

# Загрузка входного изображения input_image = cv2.imread('LR7org.jpg')

#Нормировка данных изображения и перевод во float: input_image = input_image.astype(np.float32) / 255.

#Задаем искажающую маску в виде матрицы:

PSF_blur = blur_mask(size=9, angle=35)

# Размазываем изображение:

blur_image = cv2.filter2D(input_image, -1, PSF_blur)

#Восстановление изображения методом Винера noise_var = 0.01 # подбор уровня шума image_deblur_wiener = input_image.copy()

#Обработка по трем цветовым каналам раздельно for i in range(3):

image_deblur_wiener[:, :, i] = restoration.wiener(blur_image[:, :, i], PSF_blur, noise_var)

#Ограничение и денормировка

image_deblur_wiener = np.clip(image_deblur_wiener, 0., 1.) image_deblur_wiener = (image_deblur_wiener * 255.).astype(np.uint8)

# Восстановление изображения методом Люси-Ричардсона its = 6 # количество итераций

image_deblur_rl = input_image.copy()

for i in range(3):

image_deblur_rl[:, :, i] = restoration.richardson_lucy(blur_image[:, :, i], PSF_blur, num_iter=its)

# Ограничение и денормировка

image_deblur_rl = np.clip(image_deblur_rl, 0., 1.) image_deblur_rl = (image_deblur_rl * 255.).astype(np.uint8)

# Сохранение изображений cv2.imwrite('LR7.2.jpg', image_deblur_wiener) cv2.imwrite('LR7.3.jpg', image_deblur_rl)

# Визуализация оригинального, смазанного и восстановленных изображений plt.figure(figsize=(15, 5))

plt.subplot(1, 3, 1) plt.imshow(cv2.cvtColor(blur_image, cv2.COLOR_BGR2RGB)) plt.title('Смазанное изображение')

plt.axis('off')

plt.subplot(1, 3, 2) plt.imshow(cv2.cvtColor(image_deblur_wiener, cv2.COLOR_BGR2RGB)) plt.title('Восстановленное изображение (Винер)')

plt.axis('off')

plt.subplot(1, 3, 3) plt.imshow(cv2.cvtColor(image_deblur_rl, cv2.COLOR_BGR2RGB)) plt.title('Восстановленное изображение (Люси-Ричардсон)') plt.axis('off')

plt.tight_layout() plt.show()

Рисунок 3 - Результат обработки методами восстановления изображения с помощью фильтра Винера и Люси-Ричардсона

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

передавая в функции восстановления маски, которые отличаются от используемой для смазывания. Это позволит оценить устойчивость методов восстановления, таких как Люси-Ричардсон и Винер, к ошибкам в модели пространственного фильтра (PSF). Программный код показан в листинге 3.

Листинг 3. Реализация методов восстановления изображения с помощью фильтра

Винера и Люси-Ричардсона с неправильной маской смазывания

import cv2

from skimage import restoration import numpy as np

import matplotlib.pyplot as plt

#Функция, создающая смаз: def blur_mask(size, angle):

k = np.zeros((size, size), dtype=np.float32)

k[(size - 1) // 2, :] = np.ones(size, dtype=np.float32)

k = cv2.warpAffine(k, cv2.getRotationMatrix2D((size / 2 - 0.5, size / 2 - 0.5), angle, 1.0), (size, size))

k = k / np.sum(k) # нормировка return k

#Загрузка входного изображения

input_image = cv2.imread('LR7org.jpg')

#Нормировка данных изображения и перевод во float: input_image = input_image.astype(np.float32) / 255.

#Задаем корректную искажающую маску в виде матрицы: PSF_blur = blur_mask(size=9, angle=35)

#Размазываем изображение:

blur_image = cv2.filter2D(input_image, -1, PSF_blur)

# Создание неправильной маски

incorrect_PSF = blur_mask(size=15, angle=15)

#Восстановление изображения методом Винера с неправильной маской noise_var = 0.01 # подбор уровня шума

image_deblur_wiener = input_image.copy()

#Обработка по трем цветовым каналам раздельно

for i in range(3):

image_deblur_wiener[:, :, i] = restoration.wiener(blur_image[:, :, i], incorrect_PSF, noise_var)

# Ограничение и денормировка

image_deblur_wiener = np.clip(image_deblur_wiener, 0., 1.) image_deblur_wiener = (image_deblur_wiener * 255.).astype(np.uint8)

# Восстановление изображения методом Люси-Ричардсона с неправильной маской its = 6 # количество итераций

image_deblur_rl = input_image.copy()

for i in range(3):

image_deblur_rl[:, :, i] = restoration.richardson_lucy(blur_image[:, :, i], incorrect_PSF, num_iter=its)

# Ограничение и денормировка

image_deblur_rl = np.clip(image_deblur_rl, 0., 1.) image_deblur_rl = (image_deblur_rl * 255.).astype(np.uint8)

# Сохранение изображений cv2.imwrite('LR7.4.jpg', image_deblur_wiener) cv2.imwrite('LR7.5.jpg', image_deblur_rl)

# Визуализация оригинального, смазанного и восстановленных изображений plt.figure(figsize=(15, 5))

plt.subplot(1, 3, 1) plt.imshow(cv2.cvtColor(blur_image, cv2.COLOR_BGR2RGB)) plt.title('Смазанное изображение', fontsize=9) plt.axis('off')

plt.subplot(1, 3, 2) plt.imshow(cv2.cvtColor(image_deblur_wiener, cv2.COLOR_BGR2RGB))

plt.title('Восстановленное изображение (Винер, неправильная маска)', fontsize=9)

plt.axis('off')

plt.subplot(1, 3, 3) plt.imshow(cv2.cvtColor(image_deblur_rl, cv2.COLOR_BGR2RGB))

plt.title('Восстановленное изображение (Люси-Ричардсон, неправильная маска)', fontsize=9)

plt.axis('off')

plt.tight_layout() plt.show()

Для тестирования восстановления изображений с использованием фильтров Винера и Люси-Ричардсона была выбрана неправильная маска с параметрами 15х15. Маска с размером 15x15 пикселей создаёт широкое размазывание, что приводит к заметной потере деталей изображения. Угол в

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

Результат выполнения на рисунке 4.

Рисунок 4 - Результат обработки методами восстановления изображения с помощью фильтра Винера и Люси-Ричардсона

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

градусов продолжал создавать наклонное размазывание, однако благодаря меньшему размеру маски изображение стало менее искажённым, что положительно сказалось на результатах работы алгоритмов. Результат выполнения на рисунке 5.

Рисунок 5 - Результат обработки методами восстановления изображения с помощью фильтра Винера и Люси-Ричардсона

Далее мы переходим к выполнению задания по варианту, в котором используется неравномерное размазывание. В этом случае столбец в центре маски будет представлять собой последовательность линейно возрастающих значений, что создаст более сложные условия для тестирования восстановительных алгоритмов. Мы возьмём уже имеющийся код с правильной маской и адаптируем его под новые параметры. Программой код в листинге 3. Результат представлен на рисунке 6.

Листинг 3. Реализация задания по варианту

import cv2

from skimage import restoration import numpy as np

import matplotlib.pyplot as plt

#Функция, создающая равномерный смаз def blur_mask(size, angle):

k = np.zeros((size, size), dtype=np.float32)

k[(size - 1) // 2, :] = np.ones(size, dtype=np.float32)

k = cv2.warpAffine(k, cv2.getRotationMatrix2D((size / 2 - 0.5, size / 2 - 0.5), angle, 1.0), (size, size))

k = k / np.sum(k) # Нормировка return k

#Функция, создающая маску с линейно возрастающими значениями в центральном столбце

def create_linear_blur_mask(size):

PSF = np.zeros((size, size), dtype=np.float32) center_index = size // 2

for i in range(size):

PSF[i, center_index] = i / (size - 1) # Линейное увеличение от 0 до

1

PSF /= np.sum(PSF) # Нормировка return PSF

# Загрузка входного изображения input_image = cv2.imread('LR7org.jpg')

input_image = input_image.astype(np.float32) / 255. # Нормировка данных изображения

#Создаем равномерную маску для размазывания

PSF_blur = blur_mask(size=9, angle=0)

blur_image = cv2.filter2D(input_image, -1, PSF_blur) # Размазываем изображение

#Создание маски с линейно возрастающими значениями

linear_PSF = create_linear_blur_mask(size=15) # Здесь создается маска для восстановления

#Восстановление изображения методом Винера noise_var = 0.01 # Уровень шума image_deblur_wiener = input_image.copy()

#Обработка по трем цветовым каналам раздельно for i in range(3):

image_deblur_wiener[:, :, i] = restoration.wiener(blur_image[:, :, i], linear_PSF, noise_var)

Соседние файлы в предмете Мультимедиа технологии