Что такое thresholding?
Пороговая обработка изображения (thresholding) — это базовый метод сегментации, который используется для выделения объектов на изображении путём преобразования его в бинарную форму. Основная идея заключается в сравнении значений яркости каждого пикселя с заданным порогом (threshold). Если значение пикселя выше или ниже этого порога, оно заменяется на одно фиксированное значение (обычно 255 или 0).
Основные цели thresholding
- Отделение **объекта от фона
** - Подготовка изображения к контурному анализу, распознаванию текста, **поиску формы
** -
Уменьшение информации на изображении, упрощение анализа
-
Используется как предварительный этап в более сложных системах компьютерного зрения
Простейшая бинаризация (Basic Thresholding)
Формула бинаризации:
dst(x, y) = {
maxval, если src(x, y) > T
0, если src(x, y) ≤ T
}
Где:
-
src(x, y) — значение пикселя в исходном изображении
-
dst(x, y) — значение пикселя в выходном изображении
-
T — порог
-
maxval — максимальное значение (обычно 255)
Пример:
\_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
Основные типы thresholding в OpenCV
OpenCV предоставляет несколько вариантов пороговой обработки:
-
**cv2.THRESH_BINARY
**-
Пиксели выше порога → maxval
-
Ниже порога → 0
-
-
**cv2.THRESH_BINARY_INV
**-
Инвертированная бинаризация
-
Пиксели выше порога → 0
-
Ниже порога → maxval
-
-
**cv2.THRESH_TRUNC
**-
Пиксели выше порога → заменяются на пороговое значение
-
Остальные остаются без изменений
-
-
**cv2.THRESH_TOZERO
**-
Пиксели выше порога → остаются
-
Ниже порога → становятся 0
-
-
**cv2.THRESH_TOZERO_INV
**-
Пиксели ниже порога → остаются
-
Выше порога → становятся 0
-
Пример:
import cv2
gray = cv2.imread('image.jpg', 0)
\_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
Глобальный thresholding
- Один порог T выбирается для **всего изображения
** - Подходит, если изображение имеет **однородное освещение
** - Быстро, просто, но не работает при переменной яркости
Otsu's Thresholding
Когда гистограмма изображения двухпиковая (объект и фон представлены разными яркостями), можно автоматически определить порог, минимизируя внутриклассовую дисперсию.
Суть:
-
Изображение делится на два класса (фон и объект)
-
Находится такой T, при котором **внутриклассовая дисперсия минимальна
**
В OpenCV:
\_, otsu = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
Важно: используется threshold=0, потому что значение будет определено автоматически.
Когда использовать: при наличии чётко различимых классов на изображении (например, текст на фоне, монеты на поверхности).
Адаптивный thresholding (Adaptive Thresholding)
Когда освещение неоднородное (тени, блики), глобальный порог становится неэффективным. В этом случае применяют адаптивную пороговую обработку, где порог рассчитывается для каждой области изображения.
Методы:
-
**cv2.ADAPTIVE_THRESH_MEAN_C
**- Порог = среднее значение соседних пикселей - C
-
**cv2.ADAPTIVE_THRESH_GAUSSIAN_C
**- Порог = гауссово-взвешенное среднее соседей - C
Параметры:
-
blockSize — размер соседней области (должен быть нечётным, например 11)
-
C — константа, вычитаемая из среднего
Пример:
adaptive = cv2.adaptiveThreshold(gray, 255,
cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY, 11, 2)
Гистограмма и выбор порога
Для анализа порогов часто строится гистограмма яркости изображения. Если на ней видны два чётких пика, можно попробовать глобальный порог или Otsu. Если гистограмма "плоская" или содержит много пиков, возможно потребуется адаптивный подход.
Пример гистограммы:
import matplotlib.pyplot as plt
plt.hist(gray.ravel(), 256, \[0, 256\])
plt.show()
Постобработка после thresholding
-
Фильтрация шума: морфологические операции (эрозия, дилатация)
-
Поиск контуров: cv2.findContours()
-
**Скелетизация объектов
** - **Анализ формы и размеров объектов
**
Практическое сравнение методов
Метод | Устойчив к освещению | Автоматический выбор порога | Скорость |
---|---|---|---|
Глобальный (ручной T) | ❌ | ❌ | 🔥 Быстро |
--- | --- | --- | --- |
Otsu | ❌ (если освещение неоднородное) | ✅ | 🔥 Быстро |
--- | --- | --- | --- |
Адаптивный | ✅ | ✅ (локальный) | 🐢 Медленнее |
--- | --- | --- | --- |
Трюк с гауссовым блюром + Otsu | ✅ | ✅ | ⚖ Умеренно |
--- | --- | --- | --- |
Случаи использования
-
Распознавание текста (OCR) — предварительная бинаризация
-
Медицинская визуализация — отделение опухоли от ткани
-
Анализ документов — очистка от фона
-
Контроль качества — поиск дефектов на производстве
-
Обнаружение объектов — выделение фигур для последующего анализа
Ограничения thresholding
-
Чувствительность к шуму
-
Проблемы с тенями и неоднородным освещением (в случае глобального T)
-
Может требовать дополнительной фильтрации
-
Не подходит, если объект и фон имеют похожие яркости
Расширенные техники
-
**Multilevel Thresholding
**-
Несколько порогов
-
Применяется для сегментации более чем на 2 класса
-
-
**Thresholding в цветовом пространстве
**-
Применяется к компонентам HSV, LAB, а не только к яркости
-
Позволяет отделять объекты по цвету
-
-
**Комбинирование с фильтрацией (GaussianBlur, MedianBlur)
**- Сглаживание перед бинаризацией помогает устранить шум
Thresholding в NumPy вручную
Для обучения или простых экспериментов можно реализовать thresholding без OpenCV:
import numpy as np
binary = np.where(gray > 127, 255, 0).astype(np.uint8)
Сравнение с сегментацией
Хотя thresholding — это форма сегментации, он работает только с яркостью (или цветом) и не учитывает текстуру, форму и контекст. Более продвинутые методы (например, U-Net, GrabCut, Watershed) учитывают пространственные связи и используют более сложные признаки. Thresholding же остаётся важным и быстрым методом для начальной обработки и фильтрации изображений.