Как нормализовать изображение?
Нормализация изображения — это процесс приведения пиксельных значений изображения к заданному диапазону или распределению, с целью повышения качества обработки, обучения моделей машинного обучения, улучшения визуального восприятия или повышения устойчивости алгоритмов.
Существует несколько способов нормализации, каждый из которых применяется в зависимости от задачи. Ниже подробно описаны основные подходы, примеры и объяснение, как они работают.
Зачем нужна нормализация изображения?
-
Стабильность при обучении моделей — многие алгоритмы машинного обучения чувствительны к масштабу входных данных.
-
Ускорение сходимости — при нормализованных данных градиенты лучше себя ведут.
-
Сравнение изображений — можно объективно сравнивать изображения по их структуре.
-
Устранение лишней информации — удаление смещения, освещённости и других артефактов.
Основные типы нормализации
1. Min-Max нормализация (масштабирование в диапазон [0,1] или [-1,1])
Формула:
x' = (x - min) / (max - min)
Если нужно масштабировать к диапазону [−1,1][-1, 1]:
x' = 2 * (x - min) / (max - min) - 1
Пример:
Если у вас изображение в диапазоне [0, 255], то:
normalized = image / 255.0
Это особенно полезно при работе с нейросетями, где входное распределение данных желательно в [0,1] или [-1,1].
2. Z-нормализация (стандартизация)
Формула:
x' = (x - μ) / σ
-
μμ — среднее значение всех пикселей
-
σσ — стандартное отклонение
Используется для приведения изображения к нулевому среднему и единичному стандартному отклонению.
Пример на NumPy:
normalized = (image - image.mean()) / image.std()
Применение: часто используется в сверточных нейросетях и при обучении на наборе изображений, когда требуется одинаковое распределение признаков.
3. Channel-wise Normalization (по каналам RGB)
Если изображение цветное (RGB), может быть полезно нормализовать каждый канал отдельно:
for c in range(3): # для RGB
image\[:, :, c\] = (image\[:, :, c\] - mean\[c\]) / std\[c\]
Часто используется в PyTorch, где задаются заранее известные значения mean и std для датасета (например, ImageNet):
mean = \[0.485, 0.456, 0.406\]
std = \[0.229, 0.224, 0.225\]
Зачем: чтобы модель видела изображения в таком виде, к какому она привыкла при обучении.
4. Histogram Normalization (выравнивание гистограммы)
Это метод растяжения гистограммы изображения для улучшения контраста.
Формула:
x' = (x - min) * (new_max - new_min) / (max - min) + new_min
Обычно применяется на изображениях с плохой освещённостью.
Пример (OpenCV):
img_yuv = cv2.cvtColor(image, cv2.COLOR_BGR2YUV)
img_yuv\[:, :, 0\] = cv2.equalizeHist(img_yuv\[:, :, 0\])
normalized = cv2.cvtColor(img_yuv, cv2.COLOR_YUV2BGR)
5. CLAHE (Contrast Limited Adaptive Histogram Equalization)
Это локализованная версия гистограммного выравнивания — изображение делится на участки, и на каждом применяется выравнивание с ограничением по усилению контраста.
Пример (OpenCV):
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
normalized = clahe.apply(gray)
6. Логарифмическая и гамма-коррекция
Они трансформируют яркость изображения для усиления деталей.
Гамма-коррекция:
```python
x' = x^γ
При γ < 1 изображение становится ярче, при γ > 1 — темнее.
gamma = 0.5
look_up = np.array([((i / 255.0) ** gamma) * 255 for i in np.arange(0, 256)]).astype("uint8")
normalized = cv2.LUT(image, look_up)
**Логарифмическая трансформация:
**Подходит для изображений с большим динамическим диапазоном.
<br/>```python
c = 255 / np.log(1 + np.max(image))
normalized = c \* np.log(1 + image)
normalized = np.array(normalized, dtype=np.uint8)
7. Локальная нормализация (Local Contrast Normalization)
Это метод, при котором каждый пиксель вычитается из среднего по окрестности, делённого на стандартное отклонение по окрестности.
Формула:
x'(i, j) = (x(i, j) - μ(i, j)) / σ(i, j)
Реализуется при помощи свёртки и используется для устранения локальных артефактов освещения.
8. Бинаризация как частный случай нормализации
Когда изображение приводится к двум значениям (0 и 1), это тоже можно рассматривать как нормализацию:
\_, binary = cv2.threshold(image, thresh=127, maxval=255, type=cv2.THRESH_BINARY)
Полезна для OCR, выделения объектов, анализа контуров.
Какую нормализацию выбрать?
Задача | Подходящая нормализация |
---|---|
Подготовка к CNN | Channel-wise Z-нормализация (mean/std) |
--- | --- |
Улучшение визуального качества | CLAHE, гистограммное выравнивание |
--- | --- |
Обработка в классических алгоритмах (SVM, PCA) | Z-нормализация или Min-Max |
--- | --- |
Для сравнения структур | Локальная нормализация |
--- | --- |
Сильные перепады яркости | Логарифмическая или гамма-коррекция |
--- | --- |
Особенности при использовании библиотек
OpenCV:
-
Работает с изображениями в формате uint8 или float32
-
Некоторые функции (например, cv2.equalizeHist) работают только с grayscale
PIL:
-
Требуется преобразование в массив NumPy для сложных операций
-
Занимается больше визуализацией и простыми трансформациями
NumPy:
- Универсальный способ работы с изображениями при помощи массивов
PyTorch:
-
Часто используется transforms.Normalize(mean, std)
-
Требует изображения в формате float32, нормализованные в [0,1] до стандартизации
Практический пример на PyTorch
import torchvision.transforms as transforms
transform = transforms.Compose(\[
transforms.ToTensor(), # Преобразование из \[0,255\] в \[0.0,1.0\]
transforms.Normalize(mean=\[0.485, 0.456, 0.406\],
std=\[0.229, 0.224, 0.225\])
\])
Этот подход приводит изображение к распределению, аналогичному обучающему набору ImageNet.
Таким образом, нормализация изображения — это ключевая операция, необходимая для подготовки, анализа и машинной обработки изображений. Каждый метод нормализации имеет свои особенности, применимость и цели, и выбор зависит от контекста задачи.