В предыдущей статье мы рассмотрели использование библиотеки 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()