Source code for concepts.gui.opencv.simple_text_visualizer

#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# File   : simple_text_visualizer.py
# Author : Jiayuan Mao
# Email  : maojiayuan@gmail.com
# Date   : 02/21/2024
#
# This file is part of Project Concepts.
# Distributed under terms of the MIT license.

from typing import Optional

import cv2
import numpy as np

___all__ = ['CV2SimpleTextVisualizer', 'cv2_simple_text_visualizer', 'cv2_simple_pixel_value_visualizer']


def _draw_text(
    img, text,
    font=cv2.FONT_HERSHEY_PLAIN,
    pos=(0, 0),
    font_scale=1,
    font_thickness=2,
    text_color=(0, 0, 0),
    text_color_bg=(200, 200, 200)
):
    """Adapted from: https://stackoverflow.com/questions/60674501/how-to-make-black-background-in-cv2-puttext-with-python-opencv"""
    x, y = pos
    text_size, _ = cv2.getTextSize(text, font, font_scale, font_thickness)
    text_w, text_h = text_size
    cv2.rectangle(img, (x - 5, y - 5), (x + text_w + 5, y + text_h + 5), text_color_bg, -1)
    cv2.putText(img, text, (x, y + text_h + font_scale - 1), font, font_scale, text_color, font_thickness)


[docs] class CV2SimpleTextVisualizer(object): """A simple visualizer for text. The class should be initialized with a callback function, which takes the image and the mouse position as input, and returns the text to be displayed. The visualizer will display the image and the text. Example: .. code-block:: python def callback(image, x, y): return f'Pixel value: {image[y, x]} (x={x}, y={y})' visualizer = SimpleTextVisualizer(callback) visualizer.run(image) """
[docs] def __init__(self, callback, title: Optional[str] = None, font: int = cv2.FONT_HERSHEY_SIMPLEX, font_scale: int = 1, font_thickness: int = 2): """Initialize the visualizer. Args: callback: the callback function. title: the title of the window. font: the font of the text. font_scale: the scale of the font. font_thickness: the thickness of the font. """ self.callback = callback self.font = font self.font_scale = font_scale self.font_thickness = font_thickness self.title = title if title is None: self.title = str(self) self.image = None
title: str """The title of the window.""" image: Optional[np.ndarray] """The image currently being displayed."""
[docs] def on_mouse_event(self, event, x, y, flags, param): # mouse move if event == cv2.EVENT_MOUSEMOVE: text = self.callback(self.image, x, y) image = self.image.copy() _draw_text(image, text, pos=(x, y), font=self.font, font_scale=self.font_scale, font_thickness=self.font_thickness) cv2.imshow(self.title, image)
[docs] def run(self, image: np.ndarray): self.image = image cv2.namedWindow(self.title, cv2.WINDOW_NORMAL) cv2.setMouseCallback(self.title, self.on_mouse_event) cv2.imshow(self.title, image) while True: key = cv2.waitKey(0) if key == 27 or key == ord('q'): break
[docs] def cv2_simple_text_visualizer(callback, image: np.ndarray, title: Optional[str] = None): """A simple wrapper for the SimpleTextVisualizer. See the documentation of :class:`SimpleTextVisualizer` for more details. Args: callback: the callback function. image: the image to be displayed. title: the title of the window. """ if title is None: title = 'Simple Text Visualizer' visualizer = CV2SimpleTextVisualizer(callback, title=title) visualizer.run(image)
[docs] def cv2_simple_pixel_value_visualizer(image: np.ndarray, title: Optional[str] = None): """A simple visualizer for pixel values. The visualizer will display the image and the pixel value at the mouse position. Args: image: the image to be displayed. title: the title of the window. """ def callback(f, x, y): return f'Pixel value: {f[y, x]} (x={x}, y={y})' if title is None: title = 'Simple Pixel Value Visualizer' return cv2_simple_text_visualizer(callback, image, title)