Пост

Работа с графическим интерфейсом (GUI) в OpenCV

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

Работа с графическим интерфейсом (GUI) в OpenCV

Введение

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

Создание цветовой палитры с трекбарами

Трекбары позволяют интерактивно изменять параметры и сразу видеть результат:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import numpy as np
import cv2

def empty(z):
    pass

# Создание черного изображения
image = np.zeros((300, 512, 3), np.uint8)

# Создание именованного окна
cv2.namedWindow('Palette')

# Создание трекбаров для цветовых каналов
cv2.createTrackbar('B', 'Palette', 0, 255, empty)
cv2.createTrackbar('G', 'Palette', 0, 255, empty)
cv2.createTrackbar('R', 'Palette', 0, 255, empty)

while True:
    # Отображение изображения
    cv2.imshow('Palette', image)
    
    # Выход по нажатию Esc (код 27)
    if cv2.waitKey(1) == 27:
        break
    
    # Получение текущих позиций трекбаров
    blue = cv2.getTrackbarPos('B', 'Palette')
    green = cv2.getTrackbarPos('G', 'Palette')
    red = cv2.getTrackbarPos('R', 'Palette')
    
    # Обновление цвета изображения
    image[:] = [blue, green, red]

cv2.destroyAllWindows()

Цветовая палитра с трекбарами BGR

Параметры функции createTrackbar()

Функция cv2.createTrackbar() принимает следующие аргументы:

  • name - имя трекбара
  • window_name - имя окна для привязки
  • value - начальное значение (0-255)
  • count - максимальное значение
  • onChange - функция обратного вызова при изменении

Обработка событий мыши

OpenCV позволяет обрабатывать события мыши для создания интерактивных приложений:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import numpy as np
import cv2

# Глобальные переменные для хранения координат
points = []

def mouse_callback(event, x, y, flags, param):
    global points
    
    if event == cv2.EVENT_LBUTTONDOWN:
        # Левая кнопка мыши - добавление точки
        points.append((x, y))
        print(f"Добавлена точка: ({x}, {y})")
        
    elif event == cv2.EVENT_RBUTTONDOWN:
        # Правая кнопка мыши - очистка точек
        points.clear()
        print("Все точки очищены")

# Создание белого изображения
image = np.ones((400, 600, 3), np.uint8) * 255
cv2.namedWindow('Mouse Events')
cv2.setMouseCallback('Mouse Events', mouse_callback)

while True:
    # Копия изображения для рисования
    display_image = image.copy()
    
    # Рисование всех точек
    for point in points:
        cv2.circle(display_image, point, 5, (0, 0, 255), -1)
    
    # Соединение точек линиями
    if len(points) >= 2:
        for i in range(len(points) - 1):
            cv2.line(display_image, points[i], points[i+1], (255, 0, 0), 2)
    
    cv2.imshow('Mouse Events', display_image)
    
    key = cv2.waitKey(1) & 0xFF
    if key == 27:  # Esc
        break
    elif key == ord('c'):  # Очистка по клавише 'c'
        points.clear()

cv2.destroyAllWindows()

События мыши в OpenCV

Доступные события мыши:

  • cv2.EVENT_MOUSEMOVE - движение мыши
  • cv2.EVENT_LBUTTONDOWN - нажатие левой кнопки
  • cv2.EVENT_RBUTTONDOWN - нажатие правой кнопки
  • cv2.EVENT_MBUTTONDOWN - нажатие средней кнопки
  • cv2.EVENT_LBUTTONUP - отпускание левой кнопки
  • cv2.EVENT_LBUTTONDBLCLK - двойной клик левой кнопкой

Интерактивный редактор цвета с предпросмотром

Расширенный пример с несколькими окнами и трекбарами:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import numpy as np
import cv2

def update_image(z):
    # Получение значений трекбаров
    b = cv2.getTrackbarPos('Blue', 'Controls')
    g = cv2.getTrackbarPos('Green', 'Controls')
    r = cv2.getTrackbarPos('Red', 'Controls')
    thickness = cv2.getTrackbarPos('Thickness', 'Controls')
    
    # Создание изображения с фигурами
    img = np.zeros((300, 400, 3), np.uint8)
    
    # Рисование фигур с текущим цветом
    cv2.rectangle(img, (50, 50), (150, 150), (b, g, r), thickness)
    cv2.circle(img, (200, 100), 40, (b, g, r), thickness)
    cv2.line(img, (250, 50), (350, 150), (b, g, r), thickness)
    
    # Отображение информации о цвете
    color_info = f'B:{b}, G:{g}, R:{r}'
    cv2.putText(img, color_info, (50, 200), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 1)
    
    cv2.imshow('Preview', img)

# Создание окон
cv2.namedWindow('Controls')
cv2.namedWindow('Preview')

# Создание трекбаров
cv2.createTrackbar('Blue', 'Controls', 0, 255, update_image)
cv2.createTrackbar('Green', 'Controls', 0, 255, update_image)
cv2.createTrackbar('Red', 'Controls', 0, 255, update_image)
cv2.createTrackbar('Thickness', 'Controls', 1, 10, update_image)

# Установка начальных значений
cv2.setTrackbarPos('Blue', 'Controls', 255)
cv2.setTrackbarPos('Green', 'Controls', 128)
cv2.setTrackbarPos('Red', 'Controls', 0)
cv2.setTrackbarPos('Thickness', 'Controls', 2)

# Первоначальное обновление
update_image(0)

while True:
    if cv2.waitKey(1) == 27:
        break

cv2.destroyAllWindows()

Интерактивный редактор цвета

Обработка комбинаций клавиш и мыши

Пример обработки сложных взаимодействий:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import numpy as np
import cv2

drawing = False
ix, iy = -1, -1
current_color = (0, 0, 255)  # Красный по умолчанию

def draw_circle(event, x, y, flags, param):
    global ix, iy, drawing, current_color
    
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y
        
    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing:
            cv2.circle(img, (x, y), 5, current_color, -1)
            
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        cv2.circle(img, (x, y), 5, current_color, -1)

# Создание изображения и окон
img = np.zeros((512, 512, 3), np.uint8)
cv2.namedWindow('Drawing Board')
cv2.setMouseCallback('Drawing Board', draw_circle)

# Создание трекбаров для цвета
cv2.createTrackbar('R', 'Drawing Board', 0, 255, lambda x: None)
cv2.createTrackbar('G', 'Drawing Board', 0, 255, lambda x: None)
cv2.createTrackbar('B', 'Drawing Board', 0, 255, lambda x: None)

while True:
    # Обновление цвета из трекбаров
    r = cv2.getTrackbarPos('R', 'Drawing Board')
    g = cv2.getTrackbarPos('G', 'Drawing Board')
    b = cv2.getTrackbarPos('B', 'Drawing Board')
    current_color = (b, g, r)
    
    cv2.imshow('Drawing Board', img)
    
    key = cv2.waitKey(1) & 0xFF
    if key == 27:  # Esc - выход
        break
    elif key == ord('c'):  # 'c' - очистка
        img = np.zeros((512, 512, 3), np.uint8)
    elif key == ord('s'):  # 's' - сохранение
        cv2.imwrite('drawing.png', img)
        print("Рисунок сохранен как 'drawing.png'")

cv2.destroyAllWindows()

Типичные проблемы и решения

Проблема: Трекбары не обновляют изображение в реальном времени Решение: Убедитесь, что функция обратного вызова обновляет изображение и вызывается при изменении позиции

Проблема: События мыши не обрабатываются Решение: Проверьте правильность привязки callback функции с помощью cv2.setMouseCallback()

Проблема: Медленная работа при частых обновлениях Решение: Уменьшите частоту обновления или оптимизируйте операции рисования

Проблема: Несколько окон конфликтуют Решение: Используйте уникальные имена окон и управляйте фокусом с помощью cv2.waitKey()

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

Авторский пост защищен лицензией CC BY 4.0 .

© evdokimoff. Некоторые права защищены.

Использует тему Chirpy для Jekyll