Spec-Zone.ru › scikit-learn

Примечание

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

Шумоподавление изображения с помощью обучения словаря

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

Словарь обучается на искажённой левой половине изображения, а затем используется для восстановления правой половины. Обратите внимание, что ещё лучших результатов можно было бы достичь, обучив словарь на неискажённом (то есть не содержащем шума) изображении, однако здесь мы исходим из предположения, что оно недоступно.

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

По графикам видно, что результаты ортогонального жадного поиска (OMP) с двумя ненулевыми коэффициентами немного менее смещены, чем при использовании только одного коэффициента (границы выражены менее ярко). Кроме того, результат ближе к эталонному по норме Фробениуса.

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

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

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

Создание искажённого изображения

import numpy as np
from scipy.datasets import face

raccoon_face = face(gray=True)

# Convert from uint8 representation with values between 0 and 255 to
# a floating point representation with values between 0 and 1.
raccoon_face = raccoon_face / 255.0

# downsample for higher speed
raccoon_face = (
    raccoon_face[::4, ::4]
    + raccoon_face[1::4, ::4]
    + raccoon_face[::4, 1::4]
    + raccoon_face[1::4, 1::4]
)
raccoon_face /= 4.0
height, width = raccoon_face.shape

# Distort the right half of the image
print("Distorting image...")
distorted = raccoon_face.copy()
distorted[:, width // 2 :] += 0.075 * np.random.randn(height, width // 2)
Distorting image...

Отображение искажённого изображения

import matplotlib.pyplot as plt


def show_with_diff(image, reference, title):
    """Helper function to display denoising"""
    plt.figure(figsize=(5, 3.3))
    plt.subplot(1, 2, 1)
    plt.title("Image")
    plt.imshow(image, vmin=0, vmax=1, cmap=plt.cm.gray, interpolation="nearest")
    plt.xticks(())
    plt.yticks(())
    plt.subplot(1, 2, 2)
    difference = image - reference

    plt.title("Difference (norm: %.2f)" % np.sqrt(np.sum(difference**2)))
    plt.imshow(
        difference, vmin=-0.5, vmax=0.5, cmap=plt.cm.PuOr, interpolation="nearest"
    )
    plt.xticks(())
    plt.yticks(())
    plt.suptitle(title, size=16)
    plt.subplots_adjust(0.02, 0.02, 0.98, 0.79, 0.02, 0.2)


show_with_diff(distorted, raccoon_face, "Distorted image")
Distorted image, Image, Difference (norm: 11.71)

Извлечение эталонных фрагментов

from time import time

from sklearn.feature_extraction.image import extract_patches_2d

# Extract all reference patches from the left half of the image
print("Extracting reference patches...")
t0 = time()
patch_size = (7, 7)
data = extract_patches_2d(distorted[:, : width // 2], patch_size)
data = data.reshape(data.shape[0], -1)
data -= np.mean(data, axis=0)
data /= np.std(data, axis=0)
print(f"{data.shape[0]} patches extracted in %.2fs." % (time() - t0))
Extracting reference patches...
22692 patches extracted in 0.01s.

Обучение словаря на эталонных фрагментах

from sklearn.decomposition import MiniBatchDictionaryLearning

print("Learning the dictionary...")
t0 = time()
dico = MiniBatchDictionaryLearning(
    # increase to 300 for higher quality results at the cost of slower
    # training times.
    n_components=50,
    batch_size=200,
    alpha=1.0,
    max_iter=10,
)
V = dico.fit(data).components_
dt = time() - t0
print(f"{dico.n_iter_} iterations / {dico.n_steps_} steps in {dt:.2f}.")

plt.figure(figsize=(4.2, 4))
for i, comp in enumerate(V[:100]):
    plt.subplot(10, 10, i + 1)
    plt.imshow(comp.reshape(patch_size), cmap=plt.cm.gray_r, interpolation="nearest")
    plt.xticks(())
    plt.yticks(())
plt.suptitle(
    "Dictionary learned from face patches\n"
    + "Train time %.1fs on %d patches" % (dt, len(data)),
    fontsize=16,
)
plt.subplots_adjust(0.08, 0.02, 0.92, 0.85, 0.08, 0.23)
Dictionary learned from face patches Train time 16.5s on 22692 patches
Learning the dictionary...
1.0 iterations / 105 steps in 16.46.

Извлечение зашумлённых фрагментов и их восстановление с помощью словаря

from sklearn.feature_extraction.image import reconstruct_from_patches_2d

print("Extracting noisy patches... ")
t0 = time()
data = extract_patches_2d(distorted[:, width // 2 :], patch_size)
data = data.reshape(data.shape[0], -1)
intercept = np.mean(data, axis=0)
data -= intercept
print("done in %.2fs." % (time() - t0))

transform_algorithms = [
    ("Orthogonal Matching Pursuit\n1 atom", "omp", {"transform_n_nonzero_coefs": 1}),
    ("Orthogonal Matching Pursuit\n2 atoms", "omp", {"transform_n_nonzero_coefs": 2}),
    ("Least-angle regression\n4 atoms", "lars", {"transform_n_nonzero_coefs": 4}),
    ("Thresholding\n alpha=0.1", "threshold", {"transform_alpha": 0.1}),
]

reconstructions = {}
for title, transform_algorithm, kwargs in transform_algorithms:
    print(title + "...")
    reconstructions[title] = raccoon_face.copy()
    t0 = time()
    dico.set_params(transform_algorithm=transform_algorithm, **kwargs)
    code = dico.transform(data)
    patches = np.dot(code, V)

    patches += intercept
    patches = patches.reshape(len(data), *patch_size)
    if transform_algorithm == "threshold":
        patches -= patches.min()
        patches /= patches.max()
    reconstructions[title][:, width // 2 :] = reconstruct_from_patches_2d(
        patches, (height, width // 2)
    )
    dt = time() - t0
    print("done in %.2fs." % dt)
    show_with_diff(reconstructions[title], raccoon_face, title + " (time: %.1fs)" % dt)

plt.show()
  • Orthogonal Matching Pursuit 1 atom (time: 0.6s), Image, Difference (norm: 10.69)
  • Orthogonal Matching Pursuit 2 atoms (time: 1.5s), Image, Difference (norm: 9.29)
  • Least-angle regression 4 atoms (time: 10.9s), Image, Difference (norm: 13.34)
  • Thresholding  alpha=0.1 (time: 0.1s), Image, Difference (norm: 14.23)
Extracting noisy patches...
done in 0.00s.
Orthogonal Matching Pursuit
1 atom...
done in 0.56s.
Orthogonal Matching Pursuit
2 atoms...
done in 1.54s.
Least-angle regression
4 atoms...
done in 10.91s.
Thresholding
 alpha=0.1...
done in 0.09s.

Общее время выполнения скрипта: (0 минут 30.472 секунды)

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_image_denoising.ipynb

Download Python source code: plot_image_denoising.py

Download zipped: plot_image_denoising.zip

Похожие примеры

Пример векторного квантования

Онлайн-обучение словаря фрагментов изображений лиц

Разделение изображения греческих монет на области

Распознавание рукописных цифр

© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/decomposition/plot_image_denoising.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API