Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МТ_ЛР7_Иванова_4117.docx
Скачиваний:
6
Добавлен:
29.04.2025
Размер:
11 Мб
Скачать
☆

Часть 2:

В данной части выполняется изменённая реализация первой части. А именно на основе исходной маски создаются две другие — с небольшим отклонением и выраженным. Код реализации представлен в Листинге 4. Для восстановления использовался метод Винера.

В результате можно наблюдать довольно качественное восстановленное изображение при использовании маски с небольшим отклонением (Рисунок 6). Тогда как при значительном на выходе получается мозаичная картинка — множество артефактов (Рисунок 7).

Листинг 4 — Вариант с модифицируемыми масками (метод Винера)

import cv2

from skimage import restoration

import numpy as np

# Сферическая маска расфокусировки

def spherical_blur_mask(r):

grid_size = 2 * r + 1 # Диаметр маски

y_coords, x_coords = np.ogrid[-r:r + 1, -r:r + 1] # Координатная сетка

is_inside_circle = (x_coords ** 2 + y_coords ** 2) <= (r ** 2)

mask = np.zeros((grid_size, grid_size), dtype=np.float32)

mask[is_inside_circle] = 1.0

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

return mask

# Функция для создания измененной сферической маски

def generate_modified_mask(original_radius, variation_factor):

new_radius = int(original_radius * variation_factor)

new_radius = max(1, new_radius) # радиус должен быть >=1

return spherical_blur_mask(new_radius)

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

input_imag = cv2.imread('img/p2.jpg')

input_image = input_imag.astype(np.float32) / 255.0 # Нормализация

# Основной радиус сферического размытия

base_radius = 5

PSF_blur = spherical_blur_mask(base_radius)

print(PSF_blur)

# Применение размытия

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

# Создание модифицированных масок

PSF_blur_slightly_modified = generate_modified_mask(base_radius, 1.1) # отклонение 10 %

PSF_blur_significantly_modified = generate_modified_mask(base_radius, 2) # в 2 раза

# Параметр шума

noise_var = 0.01

# Восстановление с незначительным и существенным отклонением

restored_low = input_image.copy()

restored_hight = input_image.copy()

for c in range(3): # По каналам

restored_low[:, :, c] = restoration.wiener(

blur_image[:, :, c], PSF_blur_slightly_modified, noise_var)

restored_hight[:, :, c] = restoration.wiener(

blur_image[:, :, c], PSF_blur_significantly_modified, noise_var)

# Ограничение и денормализация

restored_low = np.clip(restored_low, 0., 1.)

restored_hight = np.clip(restored_hight, 0., 1.)

restored_low = (restored_low * 255.).astype(np.uint8)

restored_hight = (restored_hight * 255.).astype(np.uint8)

path = 'img/p2'

cv2.imwrite(path+'restored_low.jpg', restored_low)

cv2.imwrite(path+'restored_hight.jpg', restored_hight)

Рисунок 6 — Восстановленное изображение (маска с отклонением 10 %)

Рисунок 7 — Восстановленное изображение (Маска с отклонением в 2 раза)

Далее реализация с изменёнными масками была повторена, ноу же с использованием в качестве способа восстановления метода Ричардсона-Люси, и выбранным на основе предыдущих опытов количеством итераций — 16. Код реализации приведен в Листинге 5. Результаты работы программы представлены на Рисунках 8-9.

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

При выраженном отклонении заметно сильное смазывание, необычное выделение контуров на контрастных участках, как будто подсвечивание (Рисунок 9).

Листинг 5 — Вариант с модифицируемыми масками (метод Ричардсона-Люси)

import cv2

from skimage import restoration

import numpy as np

# Сферическая маска расфокусировки

def spherical_blur_mask(r):

grid_size = 2 * r + 1

y_coords, x_coords = np.ogrid[-r:r + 1, -r:r + 1]

is_inside_circle = (x_coords ** 2 + y_coords ** 2) <= (r ** 2)

mask = np.zeros((grid_size, grid_size), dtype=np.float32)

mask[is_inside_circle] = 1.0

return mask / np.sum(mask)

# Генерация модифицированной маски

def generate_modified_mask(original_radius, variation_factor):

new_radius = max(1, int(original_radius * variation_factor))

return spherical_blur_mask(new_radius)

# Метод Ричардсона-Люси

def richardson_lucy_deblur(blurred_image, psf, num_iter=16):

blurred_float = blurred_image.astype(np.float32) / 255.0

deblurred = np.zeros_like(blurred_float)

for c in range(3):

deblurred[..., c] = restoration.richardson_lucy(

blurred_float[..., c], psf, num_iter=num_iter)

return np.clip(deblurred * 255, 0, 255).astype(np.uint8)

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

input_imag = cv2.imread('img/p2.jpg')

input_image = input_imag.astype(np.float32) / 255.0

# Базовая маска расфокусировки

base_radius = 5

PSF_blur = spherical_blur_mask(base_radius)

# Применяем размытие

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

# Модифицированные маски

psf_low = generate_modified_mask(base_radius, 1.1)

psf_high = generate_modified_mask(base_radius, 2)

# Восстановление методом Ричардсона–Люси

blur_image_uint8 = (blur_image * 255.).astype(np.uint8)

restored_low = richardson_lucy_deblur(blur_image_uint8, psf_low)

restored_hight = richardson_lucy_deblur(blur_image_uint8, psf_high)

path = 'img/p2'

cv2.imwrite(path+'rl_restored_low.jpg', restored_low)

cv2.imwrite(path+'rl_restored_high.jpg', restored_hight)

Рисунок 8 — Восстановленное изображение, отклонение маски 10%, метод Ричардсона-Люси

Рисунок 9 — Восстановленное изображение, отклонение маски 2 раза, метод Ричардсона-Люси