Я не уверен насчет формулы, которую вы используете для преобразования RGB в YCC , поэтому я не хочу утверждать, что это полный расчет, но чтобы упростить опубликованную вами функцию, да, используйте np.dot
с массивами вместо цифровых матриц.
np.dot
является более общим, чем *
с пустыми матрицами. При использовании *
с пустыми матрицами две матрицы должны быть 2-мерными.
Но 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))