Helpers - компьютеры, интернет, программирование

Преобразование матрицы 3x3 без петли (преобразование цвета RGB)

У меня есть изображение RGB, загруженное в массив numpy через PIL. Я получаю массив rows x cols x 3. Поработав, я пришел к следующему коду. Я хотел бы узнать, как выполнять такие манипуляции с массивом/матрицей без цикла.

# Note using matrix not array.
rgb_to_ycc = np.matrix(
     (0.2990,  0.5870,  0.1140,
    -0.1687, -0.3313,  0.5000,
     0.5000, -0.4187, -0.0813,)
).reshape( 3,3 )

ycc_to_rgb = np.matrix(
    ( 1.0, 0.0, 1.4022,
      1.0, -0.3456, -0.7145,
      1.0, 1.7710, 0, )
).reshape( 3, 3 )

def convert_ycc_to_rgb( ycc ) :
    # convert back to RGB
    rgb = np.zeros_like( ycc )
    for row in range(ycc.shape[0]) :
        rgb[row] = ycc[row] * ycc_to_rgb.T
    return rgb

def convert_rgb_to_ycc( rgb ) :
    ycc = np.zeros_like( rgb )
    for row in range(rgb.shape[0]):
        ycc[row] = rgb[row] * rgb_to_ycc.T
    return ycc

Я мог бы использовать http://pypi.python.org/pypi/colormath (через Использование Python для преобразования цветовых форматов?), но я использую это как упражнение для узнать numpy.

Вышеупомянутая библиотека Colormath использует скалярное произведение.

# Perform the adaptation via matrix multiplication.
result_matrix = numpy.dot(var_matrix, rgb_matrix)

Моя математика не там, где она должна быть. Является ли np.dot() моим лучшим выбором?

РЕДАКТИРОВАТЬ. После более глубокого чтения colormath apply_RGB_matrix()-color_conversions.py я обнаружил, что np.dot() работает, если мои преобразования 3x3 являются не матрицами. Странный.

def convert_rgb_to_ycc( rgb ) :
    return np.dot( rgb, np.asarray( rgb_to_ycc ).T )

Ответы:


1

Я не уверен в формуле, которую вы используете для преобразования RGB в YCC, поэтому не знаю Не хочу утверждать, что это полный расчет, но чтобы упростить опубликованную вами функцию, да, используйте np.dot с массивами numpy вместо матриц numpy.

np.dot более общий, чем * с пустыми матрицами. При использовании * с матрицами numpy две матрицы должны быть двумерными. Но np.dot может дать результат с массивами разной формы. Это важно для вашего приложения, поскольку rgb является трехмерным (например, когда оно имеет форму (1470, 2105, 3)).

Документы для np.dot говорят:

    For N dimensions it is a sum product over the last axis of `a` and
    the second-to-last of `b`::

        dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])

Это обобщение обычного матричного умножения.


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

Итак, ниже rgb_to_ycc — это предложенная мной функция, и я внес некоторые незначительные изменения, чтобы convert_rgb_to_ycc не вызывал исключений и выполнял вычисления, которые, как я думаю, вы намереваетесь.

Последняя строка, np.allclose(...), показывает, что две функции возвращают один и тот же результат.

import numpy as np

def rgb_to_ycc(rgb):
    M = np.array(
         (0.2990,  0.5870,  0.1140,
        -0.1687, -0.3313,  0.5000,
         0.5000, -0.4187, -0.0813,)
        ).reshape( 3,3 )
    return np.dot(rgb, M.T)

def convert_rgb_to_ycc( rgb ) :
    M = np.matrix(
         (0.2990,  0.5870,  0.1140,
        -0.1687, -0.3313,  0.5000,
         0.5000, -0.4187, -0.0813,)
        ).reshape( 3,3 )
    shape=rgb.shape
    rgb=rgb.reshape((-1,3))
    ycc = np.zeros_like( rgb )
    for i in range(len(rgb)):
        ycc[i] = rgb[i] * M.T
    return ycc.reshape(shape)

rgb=np.random.random((100,100,3))
assert np.allclose(rgb_to_ycc(rgb),convert_rgb_to_ycc(rgb))
04.11.2011
  • Ах! Использование 3x3 в качестве массива вместо матрицы действительно было решением. И встраивание матриц преобразования делает код более привлекательным. Спасибо! И np.allclose() — это что-то новое для изучения. 04.11.2011

  • 2
    def convert_ycc_to_rgb(ycc):
        return ycc * ycc_to_rgb.T
    
    def convert_rgb_to_ycc(rgb):
        return rgb * rgb_to_ycc.T
    

    так просто, вспомните, как умножение матриц определяется с точки зрения внутренних произведений строк и столбцов.

    изменить:

    Я предполагал, что матрицы rgb и ycc были просто матрицей, в которой было столько же строк, сколько пикселей, и столбец для каждого компонента цвета. Поэтому сначала нам нужно изменить их форму на (rows*cols,3), а затем обратно на (rows, cols, 3).

    Итак, наконец, код:

    def convert_ycc_to_rgb(ycc):
        shape = ycc.shape
        return np.array(ycc.reshape(-1,3) * ycc_to_rgb.T).reshape(shape)
    
    def convert_rgb_to_ycc(rgb):
        shape = rgb.shape
        return np.array(rgb.reshape(-1,3) * rgb_to_ycc.T).reshape(shape)
    
    04.11.2011
  • Я изначально так пробовал. rgb.shape, скажем, (1470, 2105, 3). rgb_to_ycc равно (3,3). ValueError: форма слишком велика, чтобы быть матрицей. 04.11.2011
  • о, понятно, я думал о сериализованных цветах пикселей... позвольте мне немного взломать это ;-) 04.11.2011
  • Новые материалы

    Интуитивное понимание тензоров в машинном обучении
    Тензор является важной концепцией во многих научных областях, таких как математика, физика, обработка сигналов и компьютерное зрение, и это лишь некоторые из них. В математике тензор — это..

    Использование машинного обучения для диагностики болезни Альцгеймера, часть 4
    Маркеры семантической согласованности для ранней диагностики болезни Альцгеймера (arXiv) Автор: Давиде Колла , Маттео Дельсанто , Марко Агосто , Бенедетто Витиелло , Даниэле Паоло Радичони..

    Почему объяснимость так важна прямо сейчас?
    По мере того, как системы искусственного интеллекта и инструменты на основе машинного обучения распространяются в нашей повседневной жизни, как практики, так и критики все чаще заявляют о..

    Анимированный математический анализ
    Использование Manim для создания математических анимированных визуализаций Визуализация данных помогает понять скрытые закономерности в данных, которые невозможно визуализировать..

    Создание простого слайдера изображений с помощью JavaScript
    Узнайте, как создать базовый слайдер изображений с помощью HTML, CSS и JavaScript. Введение В этом уроке мы создадим удобный слайдер изображений, используя JavaScript, HTML и CSS. Ползунок..

    Создание базы данных с помощью супергероя «Python»
    В этом посте мы узнаем, как создать «базу данных SQLite с помощью модуля python sqlite3, создав простую функцию входа и регистрации. Готовы ли вы к этому путешествию? Если да , давайте приступим..

    ИИ для чайников: руководство для начинающих по пониманию будущего технологий
    Вы чувствуете, что остались позади в мире ИИ? Не волнуйтесь, вы не одиноки! Со всей этой шумихой вокруг искусственного интеллекта может быть трудно понять, с чего начать. Но не позволяйте сленгу..