Статья Автор: Деникина Наталья Владимировна

Определение формы контура

Найденные контуры представляют собой огромное количество точек, проанализировать которые очень сложно. Метод cv2.approxPolyDP() используется для аппроксимации (упрощения) контуров, найденных на изображении, путём уменьшения количества точек, описывающих этот контур. Этот метод важен для уменьшения сложности контура, особенно если он состоит из большого числа точек, но при этом необходимо сохранить его основную форму.

Метод аппроксимации cv2.approxPolyDP() основан на алгоритме Рамера-Дугласа-Пекера, который позволяет упрощать кривые и контуры, оставляя лишь ключевые точки, характеризующие форму.

epsilon = 0.01 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
  • contour: Входной контур, который нужно аппроксимировать.
  • epsilon: Параметр, определяющий максимально допустимое расхождение между исходным контуром и его аппроксимированной версией. Это значение выражается в пикселях и часто задаётся как доля длины периметра контура.
  • closed: Логическое значение, указывающее, является ли контур замкнутым. Если контур замкнут, то он будет аппроксимирован замкнутым многоугольником.

В этом примере epsilon задан как 1% от длины периметра контура, что позволяет точно контролировать степень упрощения.
 

Где применяется

  • Упрощение сложных контуров: Когда контуры содержат много лишних точек, approxPolyDP помогает уменьшить их количество, сохраняя основную форму объекта.
  • Распознавание простых форм: Метод полезен для распознавания и выделения геометрических фигур, таких как треугольники, прямоугольники, многоугольники и т.д., упрощая их контуры до минимального количества точек.
  • Подготовка к дальнейшей обработке: Аппроксимация может помочь подготовить контуры к дальнейшим этапам обработки, таким как анализ формы, распознавание объектов или определение соответствий между объектами.

Проведите собственные эксперименты:

import cv2
import numpy as np


def nothing(x):
    pass


# Загрузка изображения
img = cv2.imread('image_shapes.png')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_bin = cv2.inRange(img_gray, 30, 200)

# Поиск контуров
contours, _ = cv2.findContours(img_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Создание окна с трекбаром для регулировки epsilon
cv2.namedWindow("approximation")
cv2.createTrackbar('epsilon', 'approximation', 0, 100, nothing)

while True:
    # Получение значения epsilon с трекбара
    epsilon = cv2.getTrackbarPos('epsilon', 'approximation') / 1000.0

    # Копия изображения для отрисовки контуров
    img_contours = img.copy()
    cv2.putText(img_contours, f'epsilon = {epsilon}', (170, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2)

    for contour in contours:
        # Аппроксимация контура
        approx = cv2.approxPolyDP(contour, epsilon * cv2.arcLength(contour, True), True)

        # Рисование контура (зелёный цвет)
        cv2.drawContours(img_contours, [approx], -1, (0, 125, 255), 5)

        num_points = len(approx)
        cv2.putText(img_contours, f'{num_points}', (approx[0][0][0], approx[0][0][1] - 5), cv2.FONT_HERSHEY_SIMPLEX,
                    0.5, (0, 0, 0), 2)

    # Отображение изображений
    cv2.imshow("approximation", img_contours)
    cv2.imshow("original", img)

    # Ожидание нажатия клавиши ESC для выхода
    ch = cv2.waitKey(5)
    if ch == 27:
        break

cv2.destroyAllWindows()

И вот, у вас в руках уже инструмент для контурного анализа и возможности вырезать объекты сложной формы из фона!

Пропустить Навигационные Ссылки.
Чтобы оставить комментарий нужна авторизация
Печать