mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-01 08:36:49 +08:00
Add RGB to XYZ bidi conversion.
This commit is contained in:
@@ -1,17 +1,31 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
:author: Nicolas Pinto, 2009
|
||||
"""Functions for converting between color spaces.
|
||||
|
||||
Supported color spaces
|
||||
----------------------
|
||||
- RGB
|
||||
- HSV
|
||||
- XYZ
|
||||
|
||||
Authors
|
||||
-------
|
||||
- rgb2hsv was written by Nicolas Pinto
|
||||
- hsv2rgb was written by Ralf Gommers
|
||||
- other functions were originally written by Travis Oliphant and adapted by
|
||||
Ralf Gommers
|
||||
|
||||
:license: modified BSD
|
||||
"""
|
||||
|
||||
from __future__ import division
|
||||
|
||||
__all__ = ['rgb2hsv', 'hsv2rgb']
|
||||
__all__ = ['rgb2hsv', 'hsv2rgb', 'rgb2xyz', 'xyz2rgb']
|
||||
__docformat__ = "restructuredtext en"
|
||||
|
||||
import numpy as np
|
||||
from scipy import linalg
|
||||
|
||||
|
||||
def _prepare_colorarray(arr, dtype="float32"):
|
||||
@@ -155,3 +169,59 @@ def hsv2rgb(hsv):
|
||||
out[np.isnan(out)] = 0
|
||||
|
||||
return out
|
||||
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Primaries for the coordinate systems
|
||||
#---------------------------------------------------------------
|
||||
cie_primaries = [700, 546.1, 435.8]
|
||||
sb_primaries = [1./155 * 1e5, 1./190 * 1e5, 1./225 * 1e5]
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Matrices that define conversion between different color spaces
|
||||
#---------------------------------------------------------------
|
||||
|
||||
# From sRGB specification
|
||||
xyz_from_rgb = [[0.412453, 0.357580, 0.180423],
|
||||
[0.212671, 0.715160, 0.072169],
|
||||
[0.019334, 0.119193, 0.950227]]
|
||||
|
||||
rgb_from_xyz = linalg.inv(xyz_from_rgb)
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# The conversion functions that make use of the matrices above
|
||||
#-------------------------------------------------------------
|
||||
|
||||
def _convert(matrix, arr):
|
||||
"""Do the color space conversion.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
matrix : array_like
|
||||
The 3x3 matrix to use.
|
||||
arr : ndarray
|
||||
The input array.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The converted array.
|
||||
"""
|
||||
arr = _prepare_colorarray(arr)
|
||||
arr = np.swapaxes(arr, 0, 2)
|
||||
oldshape = arr.shape
|
||||
arr = np.reshape(arr, (3, -1))
|
||||
out = np.dot(matrix, arr)
|
||||
out.shape = oldshape
|
||||
out = np.swapaxes(out, 2, 0)
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def xyz2rgb(xyz):
|
||||
return _convert(rgb_from_xyz, xyz)
|
||||
|
||||
def rgb2xyz(rgb):
|
||||
return _convert(xyz_from_rgb, rgb)
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
:author: Nicolas Pinto, 2009
|
||||
"""Tests for color conversion functions.
|
||||
|
||||
Authors
|
||||
-------
|
||||
- the rgb2hsv test was written by Nicolas Pinto, 2009
|
||||
- other tests written by Ralf Gommers, 2009
|
||||
|
||||
:license: modified BSD
|
||||
"""
|
||||
|
||||
@@ -15,6 +20,8 @@ from scikits.image.io import imread
|
||||
from scikits.image.color import (
|
||||
rgb2hsv,
|
||||
hsv2rgb,
|
||||
rgb2xyz,
|
||||
xyz2rgb
|
||||
)
|
||||
|
||||
from scikits.image import data_dir
|
||||
@@ -27,6 +34,13 @@ class TestColorconv(TestCase):
|
||||
img_rgb = imread(os.path.join(data_dir, 'color.png'))
|
||||
img_grayscale = imread(os.path.join(data_dir, 'camera.png'))
|
||||
|
||||
colbars = np.array([[1, 1, 0, 0, 1, 1, 0, 0],
|
||||
[1, 1, 1, 1, 0, 0, 0, 0],
|
||||
[1, 0, 1, 0, 1, 0, 1, 0]])
|
||||
colbars_array = np.swapaxes(colbars.reshape(3, 4, 2), 0, 2)
|
||||
colbars_point75 = colbars * 0.75
|
||||
colbars_point75_array = np.swapaxes(colbars_point75.reshape(3, 4, 2), 0, 2)
|
||||
|
||||
# RGB to HSV
|
||||
def test_rgb2hsv_conversion(self):
|
||||
rgb = self.img_rgb.astype("float32")[::16, ::16]
|
||||
@@ -67,6 +81,38 @@ class TestColorconv(TestCase):
|
||||
self.assertRaises(TypeError, hsv2rgb, [self.img_rgb[0,0]])
|
||||
|
||||
|
||||
# RGB to XYZ
|
||||
def test_rgb2xyz_conversion(self):
|
||||
gt = np.array([[[ 0.950456, 1. , 1.088754],
|
||||
[ 0.538003, 0.787329, 1.06942 ],
|
||||
[ 0.592876, 0.28484 , 0.969561],
|
||||
[ 0.180423, 0.072169, 0.950227]],
|
||||
[[ 0.770033, 0.927831, 0.138527],
|
||||
[ 0.35758 , 0.71516 , 0.119193],
|
||||
[ 0.412453, 0.212671, 0.019334],
|
||||
[ 0. , 0. , 0. ]]])
|
||||
|
||||
assert_almost_equal(rgb2xyz(self.colbars_array), gt)
|
||||
|
||||
# stop repeating the "raises" checks for all other functions that are
|
||||
# implemented with color._convert()
|
||||
def test_rgb2xyz_error_grayscale(self):
|
||||
self.assertRaises(ValueError, rgb2xyz, self.img_grayscale)
|
||||
|
||||
def test_rgb2xyz_error_one_element(self):
|
||||
self.assertRaises(ValueError, rgb2xyz, self.img_rgb[0,0])
|
||||
|
||||
def test_rgb2xyz_error_list(self):
|
||||
self.assertRaises(TypeError, rgb2xyz, [self.img_rgb[0,0]])
|
||||
|
||||
|
||||
# XYZ to RGB
|
||||
def test_xyz2rgb_conversion(self):
|
||||
# only roundtrip test, we checked rgb2xyz above already
|
||||
assert_almost_equal(xyz2rgb(rgb2xyz(self.colbars_array)),
|
||||
self.colbars_array)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_module_suite()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user