Восстановление горизонтального полноэкранного режима в OpenCV

Вопрос или проблема

Я использую версию OpenCV, которая предустановлена в Ubuntu 22.04 LTS. Ранее я настраивал свое окно OpenCV с помощью следующей конфигурации:

cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)

Это работало идеально: хотя входное изображение шире экрана, оно уменьшалось пропорционально, что позволяло мне одновременно видеть всё изображение в полноэкранном режиме (расширяясь по горизонтали). Вот пример того, как это выглядело раньше:

введите описание изображения здесь

Однако после установки (и последующей переустановки) пакетов, таких как PyQt5, PyQt5-sip и др., поведение моего окна OpenCV изменилось. Теперь, вместо того чтобы растягивать изображение по горизонтали, окно растягивает его вертикально, что искажает отображение. Вот текущее (нежелательное) поведение:

введите описание изображения здесь

Ниже представлена MRE:

import cv2
import numpy as np
from screeninfo import get_monitors

def get_screen_size():
    monitor = get_monitors()[0]
    return (monitor.width, monitor.height)

def write_text(image, text="Hello World"):
    font = cv2.FONT_HERSHEY_SIMPLEX
    font_scale = 14
    font_thickness = 14
    font_color = (255, 255, 255)
    (text_width, text_height), _ = cv2.getTextSize(text, font, font_scale, font_thickness)
    x = (image.shape[1] - text_width) // 2
    y = (image.shape[0] + text_height) // 2
    cv2.putText(image, text, (x, y), font, font_scale, font_color, font_thickness)
    return image

image = np.random.randint(0, 256, (1280, 2560, 3), dtype=np.uint8)  # тестовое изображение
image = write_text(image)
window_name="Полноэкранное изображение"
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
# cv2.resizeWindow(window_name, get_screen_size()) # 1920 x 1200 # Это мое обходное решение. Но изначально этой строки не было в коде
cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
cv2.imshow(window_name, image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Как вернуть оригинальное поведение полноэкранного режима, при котором изображение масштабируется по горизонтали, помещаясь на экран, сохраняя при этом свои пропорции?

Ответ или решение

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

Вот шаги, которые помогут вам вернуть желаемое поведение:

  1. Создание окна с флагом нормально: Используйте cv2.WINDOW_NORMAL, как это сделано в вашем коде, чтобы окно могло изменять свой размер.

  2. Настройка размера окна: Перед установкой полноэкранного режима, необходимо установить размер окна в соответствии с разрешением экрана.

  3. Использование соотношения сторон: При изменении размера изображения убедитесь, что вы сохраняете его пропорции. Это можно сделать, изменив размеры изображения в зависимости от ширины экрана.

Вот обновлённая версия вашего кода:

import cv2
import numpy as np
from screeninfo import get_monitors

def get_screen_size():
    monitor = get_monitors()[0]
    return (monitor.width, monitor.height)

def write_text(image, text="Hello World"):
    font = cv2.FONT_HERSHEY_SIMPLEX
    font_scale = 14
    font_thickness = 14
    font_color = (255, 255, 255)
    (text_width, text_height), _ = cv2.getTextSize(text, font, font_scale, font_thickness)
    x = (image.shape[1] - text_width) // 2
    y = (image.shape[0] + text_height) // 2
    cv2.putText(image, text, (x, y), font, font_scale, font_color, font_thickness)
    return image

# Создаем изображение
image = np.random.randint(0, 256, (1280, 2560, 3), dtype=np.uint8)  # пробное изображение
image = write_text(image)

window_name = "Full Screen Image"
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)

# Получаем размеры экрана
screen_width, screen_height = get_screen_size()

# Рассчитываем новый размер с сохранением пропорций
aspect_ratio = image.shape[1] / image.shape[0]
new_height = screen_height
new_width = int(aspect_ratio * new_height)

if new_width > screen_width:
    new_width = screen_width
    new_height = int(new_width / aspect_ratio)

# Устанавливаем размер окна
cv2.resizeWindow(window_name, new_width, new_height)

# Устанавливаем полноэкранный режим
cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)

# Отображаем изображение
cv2.imshow(window_name, image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Объяснение кода:

  • Мы сначала вычисляем размеры экрана с помощью get_screen_size().
  • Затем, в зависимости от исходного соотношения сторон изображения, мы вычисляем новые размеры, чтобы изображение вписалось в экран, не искажая при этом пропорции.
  • Функция cv2.resizeWindow используется для установки размера окна перед тем, как оно будет переведено в полноэкранный режим.

Этот подход должен восстановить ваше прежнее поведение окна OpenCV, при этом сохраняя подходящий вид изображения на экране.

Оцените материал
Добавить комментарий

Капча загружается...