Главная » 2025 » Ноябрь » 24 » Класс UMat: матрица с произвольными значениями
19:59
Класс UMat: матрица с произвольными значениями

Класс UMat: матрица с произвольными значениями

Стандартные классы изображений UImage, UImageRGB и UImageGray позволяют работать только с целочисленными значениями. Для значений другого типа предназначен класс UMat, который описывает матрицу с произвольными значениями. Инструкция импорта:

from unicross_image.umat import UMat

Например, можно преобразовать объект изображения в матрицу с вещественными значениями, выполнить какие-либо операции, а затем обратно преобразовать матрицу в объект изображения:

from unicross_image.ucolor import UColor
from unicross_image.uimagergb import UImageRGB

img = UImageRGB(2, 2, UColor(255, 0, 0))
print(img.arr)
# [255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0]
m = img.get_umat_64f()
print(m.arr)
# [1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0]
img = UImageRGB.from_umat_64f(m)
print(img.arr)
# [255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0]

Формат конструктора класса UMat:

UMat(width, height, num_channels=1, value=0.0, mat_type=Type_64F)

Параметры width  и height задают ширину и высоту матрицы соответственно. С помощью необязательного параметра num_channels можно указать количество каналов, а с помощью параметра value — значение по умолчанию, которое заполнит всю матрицу. Параметр mat_type задает тип данных элементов матрицы:

  • UMat.Type_8U — 8 бит (0...255);
  • UMat.Type_8S — 8 бит (-128...127);
  • UMat.Type_8B — 8 бит (True или False);
  • UMat.Type_16U — 16 бит (0...65535);
  • UMat.Type_16S — 16 бит (-32768...32767);
  • UMat.Type_32S — 32 бита (-2 147 483 648 ... 2 147 483 647);
  • UMat.Type_32F — 32 бита float (из C++);
  • UMat.Type_64F — 64 бита double (соответствует типу float в Python):
  • UMat.Type_USER — пользовательский тип.

Выведем значения констант:

print(UMat.Type_8U)   # 1
print(UMat.Type_8S)   # 2
print(UMat.Type_8B)   # 3
print(UMat.Type_16U)  # 4
print(UMat.Type_16S)  # 5
print(UMat.Type_32S)  # 6
print(UMat.Type_32F)  # 7
print(UMat.Type_64F)  # 8
print(UMat.Type_USER) # 9

Если ширина или высота меньше 1 или больше 8000, то будет сгенерировано исключение. Исключение также генерируется, если число каналов меньше одного или тип не соответствует указанным выше типам.

Пример создания матрицы с одним каналом шириной 5 элементов и высотой 1 элемент со значениями от 0.0 до 1.0:

m = UMat(5, 1)
print(m.width)         # 5 (ширина)
print(m.height)        # 1 (высота)
print(m.num_channels)  # 1 (число каналов)
print(m.arr)           # [0.0, 0.0, 0.0, 0.0, 0.0] (список)
print(len(m.arr))      # 5
print(m.arr_len)       # 5 (длина списка)
print(m.mat_type)      # 8 (тип данных)

Все атрибуты класса UMat являются общедоступными и их можно изменить извне класса. Для проверки валидности объекта предназначен метод is_valid(), который возвращает True, если все атрибуты содержат корректные значения:

m = UMat(3, 2, num_channels=3, value=0)
print(m.is_valid())    # True
m.width = -1
print(m.is_valid())    # False

Матрица может хранить как вещественные числа, так и любые другие данные, например, целые числа, описывающие компоненты цвета RGB:

m = UMat(3, 2, num_channels=3, value=0, mat_type=UMat.Type_8U)
print(m.width)         # 3
print(m.height)        # 2
print(m.num_channels)  # 3
print(m.arr)
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
print(len(m.arr))      # 18
print(m.arr_len)       # 18
print(m.mat_type)      # 1

В предыдущем примере мы указали три канала, хотя можем использовать один канал и хранить в элементах списка кортежи из трех элементов:

m = UMat(2, 2, value=(255, 0, 0), mat_type=UMat.Type_USER)
print(m.width)         # 2
print(m.height)        # 2
print(m.num_channels)  # 1
print(m.arr)
# [(255, 0, 0), (255, 0, 0), (255, 0, 0), (255, 0, 0)]
print(len(m.arr))      # 4
print(m.arr_len)       # 4
print(m.mat_type)      # 9

В основе матрицы лежит одномерный список, доступный через атрибут arr. Размер списка вычисляется следующим образом (размер доступен через атрибут arr_len):

len = width * height * num_channels

Перебрать все элементы матрицы с одним каналом можно так:

m = UMat(3, 2, num_channels=1, value=0, mat_type=UMat.Type_8U)
print(m.width)         # 3
print(m.height)        # 2
print(m.num_channels)  # 1
print(m.arr)           # [0, 0, 0, 0, 0, 0]
print(m.arr_len)       # 6
print(m.mat_type)      # 1

if m.is_valid():
    n = 1
    m_arr = m.arr
    for i in range(m.arr_len):
        m_arr[i] = n
        n += 1

print(m.arr)           # [1, 2, 3, 4, 5, 6]

Если каналов несколько, то перебрать элементы можно так:

m = UMat(2, 2, num_channels=3, value=0, mat_type=UMat.Type_8U)
print(m.width)         # 2
print(m.height)        # 2
print(m.num_channels)  # 3
print(m.arr)
# [0, 0, 0,    0, 0, 0,
#  0, 0, 0,    0, 0, 0]
print(m.arr_len)       # 12
print(m.mat_type)      # 1

if m.is_valid():
    n = 1
    m_arr = m.arr
    for i in range(0, m.arr_len, m.num_channels):
        for j in range(m.num_channels):
            m_arr[i + j] = n + j * 10
        n += 1

print(m.arr)
# [1, 11, 21,     2, 12, 22,
#  3, 13, 23,     4, 14, 24]

Чаще всего мы знаем значения, которые нужно записать в конкретный элемент. Например, записать компоненты цвета во все элементы матрицы с тремя каналами можно так:

m = UMat(2, 2, num_channels=3, value=0, mat_type=UMat.Type_8U)
if m.is_valid() and m.num_channels == 3:
    r, g, b = 255, 128, 0
    m_arr = m.arr
    for i in range(0, m.arr_len, m.num_channels):
        m_arr[i] = r
        m_arr[i + 1] = g
        m_arr[i + 2] = b

print(m.arr)
# [255, 128, 0,    255, 128, 0,
#  255, 128, 0,    255, 128, 0]

Если каналов несколько, то вычисление положения элемента внутри списка arr, при известных координатах x и y, производится по следующей формуле:

i = x * num_channels + y * width * num_channels

Например, записать компоненты цвета во все элементы матрицы с тремя каналами можно так:

m = UMat(2, 2, num_channels=3, value=0, mat_type=UMat.Type_8U)
if m.is_valid() and m.num_channels == 3:
    r, g, b = 255, 128, 0
    m_line = m.width * m.num_channels
    m_arr = m.arr
    m_num_channels = m.num_channels
    for y in range(m.height):
        for x in range(m.width):
            i = x * m_num_channels + y * m_line
            m_arr[i] = r
            m_arr[i + 1] = g
            m_arr[i + 2] = b

print(m.arr)
# [255, 128, 0,    255, 128, 0,
#  255, 128, 0,    255, 128, 0]

Класс входит в состав графической библиотеки UImage для Python 3. Описание библиотеки UImage

Категория: UImage | Просмотров: 7 | Добавил: unicross | Теги: UMat, UImage | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Категории раздела
Списки слов [10]
Списки слов и словари
OCR [4]
Оптическое распознавание символов
UImage [18]
Графическая библиотека для Python
Программы [4]
Полезные программы
Прочее [3]
Другие темы
Календарь
«  Ноябрь 2025  »
Пн Вт Ср Чт Пт Сб Вс
     12
3456789
10111213141516
17181920212223
24252627282930
Архив записей