我有一个RGB图像通过PIL加载到一个numpy阵列.我得到一行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(通过Using Python to convert color formats?),但我正在使用它作为练习学习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之后,我发现如果我的转换3x3s不是矩阵,则np.dot()有效.奇怪的.
def convert_rgb_to_ycc( rgb ) :
return np.dot( rgb, np.asarray( rgb_to_ycc ).T )
最佳答案 我不确定你使用的公式是
convert RGB to YCC,所以我不想声称这是完整的计算,但是为了简化你发布的功能,是的,使用np.dot和numpy数组而不是numpy矩阵.
np.dot比numpy矩阵更通用.当使用*与numpy矩阵时,两个矩阵必须是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))