В чём разница между бинарным и адаптивным порогом?
Разница между бинарным (глобальным) и адаптивным порогом заключается в том, как определяется значение порога (threshold), с которым сравниваются яркости пикселей изображения. Оба метода используются для бинаризации изображений, то есть перевода их в чёрно-белую (двухуровневую) форму, но работают они по-разному и предназначены для разных условий освещённости и структуры изображения.
Бинарный порог (глобальный thresholding)
Суть метода
Бинарный порог устанавливает один фиксированный порог TT для всего изображения. Все пиксели сравниваются с этим значением:
-
Если значение пикселя > TT, оно становится 255 (белое)
-
Если ≤ TT, оно становится 0 (чёрное)
Формула
dst(x, y) = {
maxval, если src(x, y) > T
0, если src(x, y) ≤ T
}
Где:
-
src(x, y) — значение яркости пикселя
-
T — выбранный порог
-
maxval — выходное значение для белого (обычно 255)
Пример в OpenCV:
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
Когда работает хорошо
-
Когда объект и фон чётко различаются по яркости
-
При **равномерном освещении
** - Для простых задач с высоким контрастом (например, чёрный текст на белом фоне)
Проблемы
- Не работает при **неоднородном освещении
** -
Может терять детали в затемнённых или пересвеченных зонах
-
Требует ручного подбора порога, если не используется автоматический метод (например, Otsu)
Адаптивный порог (adaptive thresholding)
Суть метода
Адаптивный порог не использует единое значение для всего изображения. Вместо этого каждому пикселю присваивается свой локальный порог, который рассчитывается на основе соседних пикселей (обычно в квадратном окне вокруг него).
Таким образом, он может адаптироваться к разной освещённости, теням и градиентам яркости.
Как работает
-
Для каждой точки берётся локальная область (например, 11×11 пикселей).
-
Вычисляется среднее или взвешенное среднее яркости в этой области.
-
Из этого значения вычитается небольшая константа CC.
-
Полученное значение используется как порог для текущего пикселя.
Методы адаптивного порога в OpenCV
adaptive = cv2.adaptiveThreshold(src, maxValue, method, type, blockSize, C)
Параметры:
-
method — метод вычисления локального порога:
-
cv2.ADAPTIVE_THRESH_MEAN_C — среднее значение по окрестности
-
cv2.ADAPTIVE_THRESH_GAUSSIAN_C — гауссово-взвешенное среднее
-
-
type — тип бинаризации (cv2.THRESH_BINARY, cv2.THRESH_BINARY_INV)
-
blockSize — размер локального окна (нечётное число, ≥ 3)
-
C — вычитаемое смещение (чтобы контролировать чувствительность)
Пример:
adaptive = cv2.adaptiveThreshold(gray, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY,
11, 2)
Когда работает хорошо
- При **неравномерном освещении
** -
Когда изображение содержит тени, блики, затенённые области
-
Для обработки отсканированных документов, текстур, фотографий реального мира
Визуальное сравнение
Представим себе изображение страницы, сфотографированной при боковом освещении. Левая часть ярче, правая — в тени.
Метод | Результат |
---|---|
Бинарный порог | Белые области пересвечены, тёмные — теряются |
--- | --- |
Адаптивный порог | Хорошо виден текст и слева, и справа |
--- | --- |
Сравнительная таблица
Критерий | Глобальный порог (бинарный) | Адаптивный порог |
---|---|---|
Выбор порога | Один фиксированный для всех | Разный для каждой локальной области |
--- | --- | --- |
Устойчивость к освещению | Плохо | Отлично |
--- | --- | --- |
Скорость обработки | Быстрее | Медленнее |
--- | --- | --- |
Параметры | Только T, maxval, type | blockSize, C, method, type |
--- | --- | --- |
Аппаратные требования | Низкие | Выше |
--- | --- | --- |
Гибкость | Ограниченная | Высокая |
--- | --- | --- |
Зависимость от формы объекта | Высокая | Ниже |
--- | --- | --- |
Обработка изображений с шумами | Плохо (требует фильтрации) | Лучше справляется |
--- | --- | --- |
Наилучшее применение | Чёткий контраст, равномерный свет | Неравномерный свет, тени, текст |
--- | --- | --- |
Комбинирование с другими методами
Перед применением бинарного порога полезно использовать гауссовое размытие:
```python
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
_, binary = cv2.threshold(blurred, 127, 255, cv2.THRESH_BINARY)
- В адаптивной бинаризации можно также размыть изображение, чтобы устранить шумы, особенно при низком качестве изображения.
## **Когда использовать какой метод**
| **Условие** | **Используем** |
| --- | --- |
| Равномерное освещение, чёткий фон и объект | Бинарный порог |
| --- | --- |
| Освещение переменное, есть тени и перепады | Адаптивный порог |
| --- | --- |
| Автоматический выбор порога без подбора вручную | Otsu или адаптивный |
| --- | --- |
| Высокая скорость важнее точности | Бинарный порог |
| --- | --- |
## **Особенности применения в реальных задачах**
- **OCR (распознавание текста)
**
- Бинаризация является обязательным шагом.
- Адаптивный порог даёт лучший результат на фото с освещением или шумом.
- **Анализ структуры ткани в медицине
**
- Используются локальные пороги, т.к. снимки часто имеют сложное освещение.
- **Контроль качества на производстве
**
- Бинаризация помогает выделить дефекты, трещины, сколы на материалах.
- **Распознавание документов
**
- Сканированные документы с фоном или помятые — адаптивная бинаризация даёт стабильный результат.
- **Подсчёт объектов (зерна, клетки, капли)
**
- Начинается с пороговой обработки, затем используется cv2.findContours.
## **Технические замечания**
- blockSize должен быть достаточно большим, чтобы охватывать весь локальный фон, но не слишком большим, иначе исчезает адаптивность.
- Константа C играет роль "смещения" — увеличивает или уменьшает чувствительность к локальным изменениям.
- Адаптивный метод не требует ручного выбора глобального порога, но требует настройки blockSize и C — часто подбирается эмпирически.
## **Сравнение на практике**
Пример с OpenCV:
```python
import cv2
gray = cv2.imread('doc.jpg', cv2.IMREAD_GRAYSCALE)
\# Глобальный порог
\_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
\# Адаптивный порог
adaptive = cv2.adaptiveThreshold(gray, 255,
cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY,
11, 2)
cv2.imshow('Global', binary)
cv2.imshow('Adaptive', adaptive)
cv2.waitKey(0)
cv2.destroyAllWindows()
Такой код наглядно показывает разницу, особенно на изображениях с неравномерной освещённостью, текстурой, тенями.