Неделя 6 - Сегментация изображений и анализ контуров
1. Введение в сегментацию изображений
Сегментация - процесс разделения изображения на значимые части. Основные подходы:
Пороговая обработка
Краевая сегментация
Областная сегментация
Кластеризация
2. Пороговая обработка
2.1. Простое пороговое разделение
python
Copy
import cv2
import numpy as np
img = cv2.imread('objects.jpg', 0) # Загрузка в градациях серого
# Простое пороговое разделение
_, thresh_bin = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
_, thresh_inv = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
cv2.imshow('Original', img)
cv2.imshow('Binary', thresh_bin)
cv2.imshow('Inverse Binary', thresh_inv)
cv2.waitKey(0)
2.2. Адаптивный порог
python
Copy
# Адаптивный порог (для неравномерного освещения)
thresh_adapt = cv2.adaptiveThreshold(img, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2)
2.3. Метод Оцу
python
Copy
# Автоматический подбор порога
_, thresh_otsu = cv2.threshold(img, 0, 255,
cv2.THRESH_BINARY+cv2.THRESH_OTSU)
3. Поиск контуров
3.1. Основная функция findContours
python
Copy
# Поиск контуров (используйте бинарное изображение)
contours, hierarchy = cv2.findContours(thresh_bin,
cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)
# Рисование контуров
contour_img = cv2.cvtColor(thresh_bin, cv2.COLOR_GRAY2BGR)
cv2.drawContours(contour_img, contours, -1, (0,255,0), 2)
3.2. Режимы поиска контуров
cv2.RETR_EXTERNAL - только внешние контуры
cv2.RETR_LIST - все контуры без иерархии
cv2.RETR_TREE - все контуры с иерархией
3.3. Методы аппроксимации
cv2.CHAIN_APPROX_NONE - сохраняет все точки
cv2.CHAIN_APPROX_SIMPLE - сжимает контуры
4. Анализ контуров
4.1. Основные характеристики
python
Copy
for cnt in contours:
# Площадь контура
area = cv2.contourArea(cnt)
# Периметр/длина контура
perimeter = cv2.arcLength(cnt, True)
# Ограничивающий прямоугольник
x,y,w,h = cv2.boundingRect(cnt)
# Минимальная площадь прямоугольника
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
# Минимальная окружность
(x,y), radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
# Эллипс
if len(cnt) >= 5:
ellipse = cv2.fitEllipse(cnt)
4.2. Моменты контура
python
Copy
for cnt in contours:
M = cv2.moments(cnt)
if M['m00'] != 0:
cx = int(M['m10']/M['m00']) # Центр масс по X
cy = int(M['m01']/M['m00']) # Центр масс по Y
cv2.circle(contour_img, (cx,cy), 5, (255,0,0), -1)
5. Методы кластеризации
5.1. K-means кластеризация
python
Copy
# Подготовка данных (векторизация изображения)
pixel_values = img.reshape((-1, 3))
pixel_values = np.float32(pixel_values)
# Критерии остановки
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.2)
# Кластеризация
k = 3
_, labels, centers = cv2.kmeans(pixel_values, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
# Восстановление изображения
centers = np.uint8(centers)
segmented_data = centers[labels.flatten()]
segmented_img = segmented_data.reshape((img.shape))
6. Водораздельная сегментация
python
Copy
# Маркеры для водораздела
_, markers = cv2.connectedComponents(thresh_bin)
markers = markers + 1
markers[thresh_bin == 0] = 0
# Применение алгоритма
markers = cv2.watershed(cv2.cvtColor(img, cv2.COLOR_GRAY2BGR), markers)
img[markers == -1] = [255,0,0] # Границы водораздела
7. Практическое задание
1. Примените различные методы пороговой обработки к изображению
2. Найдите и визуализируйте контуры объектов
3. Вычислите характеристики контуров (площадь, периметр)
4. Проведите кластеризацию изображения методом K-means
5. Реализуйте водораздельную сегментацию
8. Итоги
Пороговая обработка - базовый метод сегментации
Контуры позволяют анализировать форму объектов
Кластеризация группирует пиксели по схожести
Водораздельный алгоритм эффективен для сложных сцен
Следующая тема: Морфологические операции и работа с бинарными изображениями