В предыдущей статье мы рассмотрели использование библиотеки OpenCV для распознавания и обводки карт на изображении стола. Однако, как мы отметили, алгоритм не работал идеально в центральной области стола. В этой статье мы продолжим развитие нашего алгоритма, внесем улучшения и исправим недочеты.

Шаг 7: Определение регионов интереса

Один из основных факторов, влияющих на работу нашего алгоритма, - это определение регионов интереса на изображении. Мы выделили три области на столе с картами: боковую, среднюю и нижнюю области.

Для определения регионов интереса, в которых находятся карты, мы используем найденные контуры карт. После нахождения каждого контура, мы проверяем его координаты и сравниваем их с координатами каждой области regions_of_interest. Если координаты контура попадают в одну из областей, мы считаем, что карта находится в этой области.

Шаг 8: Оптимизация

Мы улучшили метод process_screen класса ScreenCapture, добавив этот функционал. Обновленный код метода выглядит следующим образом:

def process_screen(self, image):
    # Преобразование изображения в оттенки серого
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # Фильтр для извлечения белого цвета
    mask = cv2.inRange(image, self.gray_lower_white, self.gray_upper_white)

    # Морфологические операции для удаления шума
    opened = cv2.morphologyEx(mask, cv2.MORPH_OPEN, self.kernel, iterations=0)

    # Поиск контуров на обработанном изображении
    contours, _ = cv2.findContours(opened, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # Определение координат карт в регионах интереса
    for contour in contours:
        x, y, w, h = cv2.boundingRect(contour)
        if (
            self.min_rectangle_size <= w <= self.max_rectangle_size
            and self.min_rectangle_size <= h <= self.max_rectangle_size
        ):
            for roi in self.regions_of_interest:
                roi_x, roi_y, roi_w, roi_h = roi
                if roi_x <= x <= roi_x + roi_w and roi_y <= y <= roi_y + roi_h:
                    print("Координаты карты:", x, y, x + w, y + h)

Шаг 9: Уточнение параметров фильтрации

Для улучшения алгоритма мы также провели настройку параметров фильтрации и морфологических операций. Используя экспериментальный подход, мы определили, что значения gray_lower_white и gray_upper_white подходят для фильтрации белого цвета на изображении. Также, параметры морфологической операции cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) были выбраны оптимальными для удаления шума на изображении.

Шаг 9: Тестирование и анализ результатов

После внесения улучшений мы запустили программу и провели тестирование на различных изображениях столов с картами. Результаты были впечатляющими. Алгоритм успешно находил карты во всех трех регионах интереса, включая центральную область стола. Теперь наш алгоритм работает более точно и надежно.

Заключение

В этой статье мы улучшили алгоритм поиска и распознавания карт на изображении с использованием библиотеки OpenCV. Мы добавили определение регионов интереса, что позволило нам точнее определять положение карт на столе. Мы также уточнили параметры фильтрации и морфологических операций, чтобы улучшить качество обработки изображения. Теперь наш алгоритм способен найти и обвести карты на столе с высокой точностью. Распознавание обьектов лишь часть проекта за которым можно следить здесь

PUMOVETZ/The-Fool-Game (github.com)

Теперь результат работы алгоритма выглядит так.

Вот полный код

import cv2
import numpy as np
import time


target_resolution = (1920, 1080)


image = cv2.imread("im3.png")




regions_of_interest = [
    (20, 250, 180, 550),
    (200, 270, 1780, 560),
    (30, 555, 1850, 900),
]


gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)


lower_white = np.array([220, 220, 220])
upper_white = np.array([255, 255, 255])
mask = cv2.inRange(image, lower_white, upper_white)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
opened = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=0)

contours, _ = cv2.findContours(opened, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

min_rectangle_size = 80
max_rectangle_size = 400

for contour in contours:
    x, y, w, h = cv2.boundingRect(contour)
    if min_rectangle_size <= w <= max_rectangle_size and min_rectangle_size <= h <= max_rectangle_size:
        for roi in regions_of_interest:
            roi_x, roi_y, roi_w, roi_h = roi
            if roi_x <= x <= roi_x + roi_w and roi_y <= y <= roi_y + roi_h:
                cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
                break

image = cv2.resize(image, (1280, 720))
cv2.imshow('Processed Image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Комментарии (0)