def hsv2rgb(self, color): hue = color.value[0] * 360. / 255. / 360. * 6 saturation = color.value[1] / 255. value = color.value[2] / 255. chroma = value * saturation x = chroma * (1 - math.fabs(hue % 2 - 1)) rgb = [0] * Color.COLOR_DIM hue = hue % 6 if 0. <= hue < 1.: rgb = [chroma, x, 0] if 1. <= hue < 2.: rgb = [x, chroma, 0] if 2. <= hue < 3.: rgb = [0, chroma, x] if 3. <= hue < 4.: rgb = [0, x, chroma] if 4. <= hue < 5.: rgb = [x, 0, chroma] if 5. <= hue < 6.: rgb = [chroma, 0, x] min_val = value - chroma return Color( ColorSpace("RGB"), np.round((np.array(rgb) + min_val) * 255).astype(np.uint8))
def rgb2hsv(self, color): color.value = color.value / 255. red, green, blue = color.value.tolist() max_val = max(color.value) min_val = min(color.value) diff = max_val - min_val if diff == 0: hue = 0 elif max_val == red: hue = (green - blue) / diff elif max_val == green: hue = (blue - red) / diff + 2 elif max_val == blue: hue = (red - green) / diff + 4 hue *= 60 hue = hue + 360 if hue < 0 else hue saturation = 0 if max_val == 0 else diff / max_val * 255 value = max_val * 255 hue *= 255. / 360. return Color( ColorSpace("HSV"), np.round(np.array([hue, saturation, value])).astype(np.uint8))
def __init__(self, space=ColorSpace(), value=np.zeros(3, np.uint8)): if value.size != self.COLOR_DIM: raise InvalidColorError('invalid color size') if value[value < 0].size != 0 or value[value > 255].size != 0: raise InvalidColorError('invalid color values') self.space = space self.value = value
def lab2rgb(self, color): l, a, b = color.value.tolist() # Convert Lab to XYZ. y = (l * 100. / 255. + 16.0) / 116.0 x = (a - 128.) / 500. + y z = y - (b - 128.) / 200. xyz = np.multiply( list(map(utility.xyz2lab_nonlinear_transform_inv, [x, y, z])), ColorSpaceConverter.WHITE_POINT) # Convert XYZ to RGB. rgb = np.divide( inv(ColorSpaceConverter.RGB2XYZ_CONVERSION_MAT).dot(xyz), 100.) vec_func = np.vectorize(utility.rgb2xyz_nonlinear_transform_inv) rgb = np.multiply(vec_func(rgb), 255.) rgb[rgb < 0] = 0 return Color(ColorSpace("RGB"), np.round(rgb).astype(np.uint8))
def rgb2lab(self, color): color.value = color.value / 255. # Convert RGB to XYZ. red, green, blue = [ val * 100. for val in map(utility.rgb2xyz_nonlinear_transform, color.value.tolist()) ] xyz = ColorSpaceConverter.RGB2XYZ_CONVERSION_MAT.dot( np.array([red, green, blue], dtype=np.float32)) # Convert XYZ to Lab. xyz = np.divide(xyz, ColorSpaceConverter.WHITE_POINT) x_norm, y_norm, z_norm = map(utility.xyz2lab_nonlinear_transform, xyz.tolist()) l = (116. * y_norm - 16.) * 255. / 100. a = 500. * (x_norm - y_norm) + 128 b = 200. * (y_norm - z_norm) + 128 return Color(ColorSpace("LAB"), np.round(np.array([l, a, b])).astype(np.uint8))
class Color: COLOR_DIM = 3 value = np.zeros(COLOR_DIM, np.uint8) space = ColorSpace() def __init__(self, space=ColorSpace(), value=np.zeros(3, np.uint8)): if value.size != self.COLOR_DIM: raise InvalidColorError('invalid color size') if value[value < 0].size != 0 or value[value > 255].size != 0: raise InvalidColorError('invalid color values') self.space = space self.value = value def __str__(self): return "{} {}".format(self.space, self.value.tolist()) def __eq__(self, other_color): eq_space = self.space == other_color.space eq_value = np.array_equal(self.value, other_color.value) return eq_space and eq_value
def test_can_convert_lab_to_rgb_1(self): color = Color(ColorSpace("LAB"), np.array([80, 79, 185])) rgb_color = self.converter.convert(color, ColorSpace("RGB")) self.assertEqual(rgb_color, Color(ColorSpace("RGB"), np.array([0, 89, 0])))
def test_can_convert_rgb_to_hsv_1(self): color = Color(ColorSpace("RGB"), np.array([191, 71, 123])) hsv_color = self.converter.convert(color, ColorSpace("HSV")) self.assertEquals(hsv_color, Color(ColorSpace("HSV"), np.array([237, 160, 191])))
def test_can_convert_simple_rgb_to_hsv(self): color = Color(ColorSpace("RGB"), np.array([0, 100, 0])) hsv_color = self.converter.convert(color, ColorSpace("HSV")) self.assertEquals(hsv_color, Color(ColorSpace("HSV"), np.array([85, 255, 100])))
def test_can_convert_rgb_to_rgb(self): color = Color() rgb_color = self.converter.convert(color, ColorSpace("RGB")) self.assertEqual(color, rgb_color)
def test_can_create_rgb_color(self): color = Color(ColorSpace("RGB"), np.array([123, 45, 67])) self.assertEqual( str(color), "{} {}".format("RGB", np.array([123, 45, 67]).tolist()))
def test_can_create_default_hsv_color(self): color = Color(ColorSpace("HSV")) self.assertEqual(str(color), "HSV [0, 0, 0]")
def test_can_convert_hsv_to_rgb_4(self): color = Color(ColorSpace("HSV"), np.array([142, 50, 60])) rgb_color = self.converter.convert(color, ColorSpace("RGB")) self.assertEqual(rgb_color, Color(ColorSpace("RGB"), np.array([48, 56, 60])))
def test_can_convert_simple_hsv_to_rgb(self): color = Color(ColorSpace("HSV"), np.array([0, 100, 0])) rgb_color = self.converter.convert(color, ColorSpace("RGB")) self.assertEqual(rgb_color, Color(ColorSpace("RGB"), np.array([0, 0, 0])))
def test_can_convert_black_hsv_to_rgb(self): color = Color(ColorSpace("HSV")) rgb_color = self.converter.convert(color, ColorSpace("RGB")) self.assertEqual(rgb_color, Color(ColorSpace("RGB")))
def test_cannot_create_unimplemented_converter(self): color = Color(ColorSpace("HSV")) with self.assertRaises(InvalidConversion): self.converter.convert(color, ColorSpace("LAB"))
def test_cannot_create_invalid_color_space_type(self): with self.assertRaises(InvalidColorSpace): ColorSpace(1)
def test_can_create_default_rgb_color_space(self): color_space = ColorSpace() self.assertEqual(str(color_space), "RGB")
def test_can_create_default_lab_color(self): color = Color(ColorSpace("LAB")) self.assertEqual(str(color), "LAB [0, 0, 0]")
def test_can_convert_hsv_to_rgb_6(self): color = Color(ColorSpace("HSV"), np.array([247, 108, 123])) rgb_color = self.converter.convert(color, ColorSpace("RGB")) self.assertEqual(rgb_color, Color(ColorSpace("RGB"), np.array([123, 71, 81])))
def test_cannot_create_invalid_rgb_color_val_neg(self): rand_color = np.random.randint(-100, -10, size=(1, Color.COLOR_DIM)) with self.assertRaises(InvalidColorError): Color(ColorSpace("RGB"), rand_color)
def test_can_convert_black_rgb_to_lab(self): color = Color() lab_color = self.converter.convert(color, ColorSpace("LAB")) self.assertEqual(lab_color, Color(ColorSpace("LAB"), np.array([0, 128, 128])))
def test_can_convert_black_rgb_to_hsv(self): color = Color() hsv_color = self.converter.convert(color, ColorSpace("HSV")) self.assertEqual(hsv_color, Color(ColorSpace("HSV")))
def test_can_convert_simple_rgb_to_lab(self): color = Color(ColorSpace("RGB"), np.array([0, 100, 0])) lab_color = self.converter.convert(color, ColorSpace("LAB")) self.assertEqual(lab_color, Color(ColorSpace("LAB"), np.array([92, 85, 170])))
def test_can_create_empty_color_space(self): color_space = ColorSpace() self.assertTrue(isinstance(color_space, ColorSpace))
def test_can_convert_rgb_to_lab(self): color = Color(ColorSpace("RGB"), np.array([91, 71, 123])) lab_color = self.converter.convert(color, ColorSpace("LAB")) self.assertEqual(lab_color, Color(ColorSpace("LAB"), np.array([88, 148, 101])))
def convert(self): a = np.array(list(map(int, self.color_in))) color = Color(ColorSpace(self.color_space_in), a) converted_color = self.converter.convert(color, ColorSpace(self.color_space_out)) self.color_out = list(map(str, converted_color.value.tolist())) self.logger.log("Input color: " + str(color) + " --> " + "Output color: " + str(converted_color))
def test_can_convert_lab_to_rgb(self): color = Color(ColorSpace("LAB"), np.array([88, 148, 101])) rgb_color = self.converter.convert(color, ColorSpace("RGB")) self.assertEqual(rgb_color, Color(ColorSpace("RGB"), np.array([90, 72, 124])))