I'm trying to do this code just with NumPy
I have used skimage but it is not perfect like tfio rgb_to_xyz
so
def rgb_to_xyz(input, name=None):
"""
Convert a RGB image to CIE XYZ.
Args:
input: A 3-D (`[H, W, 3]`) or 4-D (`[N, H, W, 3]`) Tensor.
name: A name for the operation (optional).
Returns:
A 3-D (`[H, W, 3]`) or 4-D (`[N, H, W, 3]`) Tensor.
"""
input = tf.convert_to_tensor(input)
assert input.dtype in (tf.float16, tf.float32, tf.float64)
kernel = tf.constant(
[
[0.412453, 0.357580, 0.180423],
[0.212671, 0.715160, 0.072169],
[0.019334, 0.119193, 0.950227],
],
input.dtype,
)
value = tf.where(
tf.math.greater(input, 0.04045),
tf.math.pow((input 0.055) / 1.055, 2.4),
input / 12.92,
)
return tf.tensordot(value, tf.transpose(kernel), axes=((-1,), (0,)))
CodePudding user response:
Here is an implementation using NumPy:
def rgb_to_xyz(rgb):
"""
Convert a RGB image to CIE XYZ.
Args:
input: A 3-D (`[H, W, 3]`).
Returns:
A 3-D (`[H, W, 3]`).
"""
if rgb.dtype == 'uint8':
rgb = rgb.astype(float)/255 # Convert range from [0, 255] to [0, 1]
# If not uint8, assume type is float64 or float32 in range [0, 1]
# Inverse sRGB Gamma (convert to "linear RGB")
lin_rgb = rgb / 12.92
lin_rgb[rgb > 0.04045] = ((rgb[rgb > 0.04045] 0.055) / 1.055) ** 2.4
k = np.array([
[0.412453, 0.357580, 0.180423],
[0.212671, 0.715160, 0.072169],
[0.019334, 0.119193, 0.950227],
], rgb.dtype)
# Left multiply k by lin_rgb triplets. xyz[r, c] = k * lin_rgb[r, c] (use k.T and reverse order for using matmul).
xyz = np.matmul(lin_rgb, k.T)
return xyz
I think 4-D input is supported due to NumPy broadcasting rules.