Skip to content

Commit

Permalink
Merge branch 'master' into kainov-oleg-lab1
Browse files Browse the repository at this point in the history
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
  • Loading branch information
okainov committed Nov 5, 2015
2 parents 67b09d7 + 62937dc commit 05b1ce2
Show file tree
Hide file tree
Showing 7 changed files with 384 additions and 0 deletions.
31 changes: 31 additions & 0 deletions code/khanova-tatiana/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Перевод из одного цветового пространства в другое (RGB, HSV, LAB)

Выполнилa:

- Ханова Татьяна
- ННГУ, ИИТММ, каф. МОСТ, группа M0823-1

## Задание

Реализовать класс конвертер, который должен предоставлять возможность перевода из одного цветового пространства в другое. Требуется поддержка следующих цветовых пространств:

- RGB
- HSV
- LAB

Класс должен позволять работать с заданным цветом в одном из цветовых пространств

Все необходимые математические сведения по цветовым пространствам можно найти в статьях
["HSV"][HSV], ["RGB"][RGB], ["LAB"][LAB] на сайте Wikipedia. Были использованы формулы для перевода и нормировки значений аналогичные [OpenCV][doc].

## Документация разработчика

TBD

<!-- LINKS -->

[HSV]: https://en.wikipedia.org/wiki/HSL_and_HSV
[RGB]: https://en.wikipedia.org/wiki/RGB_color_model
[LAB]: https://en.wikipedia.org/wiki/Lab_color_space
[doc]: http://docs.opencv.org/2.4.11/modules/imgproc/doc/miscellaneous_transformations.html#cvtcolor

31 changes: 31 additions & 0 deletions code/khanova-tatiana/src/color.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import numpy as np
from color_space import ColorSpace


class InvalidColorError(Exception):
pass


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
20 changes: 20 additions & 0 deletions code/khanova-tatiana/src/color_space.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class InvalidColorSpace(Exception):
pass


class ColorSpace:
SUPPORTED_COLOR_SPACES = ["RGB", "HSV", "LAB"]

color_space = "RGB"

def __init__(self, color_space="RGB"):
if color_space not in self.SUPPORTED_COLOR_SPACES:
raise InvalidColorSpace(
'unsupported color space: ' + str(color_space))
self.color_space = color_space

def __str__(self):
return self.color_space

def __eq__(self, other):
return self.color_space == other.color_space
106 changes: 106 additions & 0 deletions code/khanova-tatiana/src/color_space_converter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import numpy as np
import math
from color import Color
from color_space import ColorSpace
import utility


class InvalidConversion(Exception):
pass


class ColorSpaceConverter:
@staticmethod
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 *= 0.5

return Color(ColorSpace("HSV"),
np.round(np.array([hue, saturation, value])))

@staticmethod
def hsv2rgb(self, color):
hue = color.value[0] * 2. / 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))

@staticmethod
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())]

conversion_mat = np.array([[0.412453, 0.357580, 0.180423],
[0.212671, 0.715160, 0.072169],
[0.019334, 0.119193, 0.950227]])

xyz = conversion_mat.dot(
np.array([red, green, blue], dtype=np.float32))

# Convert XYZ to Lab.
ref_point = np.array([95.047, 100., 108.883])

x_norm, y_norm, z_norm = map(utility.xyz2lab_nonlinear_transform,
np.divide(xyz, ref_point).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])))

def convert(self, color, dst_space):
if color.space == dst_space:
return color

converter_name = "{}2{}".format(color.space, dst_space).lower()
if hasattr(ColorSpaceConverter, converter_name):
color_pair_func = getattr(ColorSpaceConverter, converter_name)
return color_pair_func(self, color)
else:
raise InvalidConversion("no converter for: " + converter_name)
163 changes: 163 additions & 0 deletions code/khanova-tatiana/src/test_color_space.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import unittest
import numpy as np

from color_space import ColorSpace, InvalidColorSpace
from color import Color, InvalidColorError
from color_space_converter import ColorSpaceConverter, InvalidConversion


class TestColorSpaceClass(unittest.TestCase):
def test_can_create_empty_color_space(self):
color_space = ColorSpace()
self.assertTrue(isinstance(color_space, ColorSpace))

def test_can_create_default_rgb_color_space(self):
color_space = ColorSpace()
self.assertEqual(str(color_space), "RGB")

def test_cannot_create_invalid_color_space(self):
with self.assertRaises(InvalidColorSpace):
ColorSpace("QQQ")

def test_cannot_create_invalid_color_space_type(self):
with self.assertRaises(InvalidColorSpace):
ColorSpace(1)


class TestColorClass(unittest.TestCase):
def test_can_create_empty_color(self):
color = Color()
self.assertTrue(isinstance(color, Color))

def test_can_create_default_rgb_color(self):
color = Color()
self.assertEqual(str(color), "RGB [0, 0, 0]")

def test_can_create_default_hsv_color(self):
color = Color(ColorSpace("HSV"))
self.assertEqual(str(color), "HSV [0, 0, 0]")

def test_can_create_default_lab_color(self):
color = Color(ColorSpace("LAB"))
self.assertEqual(str(color), "LAB [0, 0, 0]")

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_cannot_create_invalid_rgb_color_len(self):
rand_color = np.random.randint(0, 255, size=(1, 10))
with self.assertRaises(InvalidColorError):
Color("RGB", rand_color)

def test_cannot_create_invalid_rgb_color_val(self):
rand_color = np.random.randint(300, 400, size=(1, Color.COLOR_DIM))
with self.assertRaises(InvalidColorError):
Color(ColorSpace("RGB"), rand_color)

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)


class TestColorSpaceConverterClass(unittest.TestCase):
def setUp(self):
self.converter = ColorSpaceConverter()

def test_can_create_color_space_converter(self):
self.assertTrue(isinstance(self.converter, ColorSpaceConverter))

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_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_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([60, 255, 100])))

def test_can_convert_rgb_to_hsv(self):
color = Color(ColorSpace("RGB"), np.array([91, 71, 123]))
hsv_color = self.converter.convert(color, ColorSpace("HSV"))
self.assertEquals(hsv_color, Color(ColorSpace("HSV"),
np.array([132, 108, 123])))

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([167, 160, 191])))

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_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_hsv_to_rgb_2(self):
color = Color(ColorSpace("HSV"), np.array([40, 108, 123]))
rgb_color = self.converter.convert(color, ColorSpace("RGB"))
self.assertEqual(rgb_color, Color(ColorSpace("RGB"),
np.array([106, 123, 71])))

def test_can_convert_hsv_to_rgb_3(self):
color = Color(ColorSpace("HSV"), np.array([80, 108, 123]))
rgb_color = self.converter.convert(color, ColorSpace("RGB"))
self.assertEqual(rgb_color, Color(ColorSpace("RGB"),
np.array([71, 123, 106])))

def test_can_convert_hsv_to_rgb_4(self):
color = Color(ColorSpace("HSV"), np.array([100, 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_hsv_to_rgb_5(self):
color = Color(ColorSpace("HSV"), np.array([132, 108, 123]))
rgb_color = self.converter.convert(color, ColorSpace("RGB"))
self.assertEqual(rgb_color, Color(ColorSpace("RGB"),
np.array([92, 71, 123])))

def test_can_convert_hsv_to_rgb_6(self):
color = Color(ColorSpace("HSV"), np.array([175, 108, 123]))
rgb_color = self.converter.convert(color, ColorSpace("RGB"))
self.assertEqual(rgb_color, Color(ColorSpace("RGB"),
np.array([123, 71, 80])))

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_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.0, 85.0, 170.0])))

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 test_cannot_create_unimplemented_converter(self):
color = Color(ColorSpace("LAB"))
with self.assertRaises(InvalidConversion):
self.converter.convert(color, ColorSpace("RGB"))
15 changes: 15 additions & 0 deletions code/khanova-tatiana/src/utility.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import math


def xyz2lab_nonlinear_transform(t):
if t > 0.008856:
return math.pow(t, 1. / 3)
else:
return 7.787 * t + 16. / 116


def rgb2xyz_nonlinear_transform(t):
if t <= 0.04045:
return t / 12.92
else:
return math.pow(((t + 0.055) / 1.055), 2.4)
18 changes: 18 additions & 0 deletions code/timonova-anastasia/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Матрицы. Заполнение, вычисление детерминанта

### Выполнила:

- Тимонова Анастасия
- ННГУ, ИИТММ, каф. МОСТ, группа М0816-1

### Задание:
1. Разработать приложение для заполнения матрицы и вычисления её детерминанта.
2. Для матриц более высокого порядка, чем 2х2 или 3х3, при необходимости, можно использовать метод Гаусса для повышения эффективности вычислений.

Некоторые сведения можно найти в учебной литературе и статьях:
- А.Г. Курош ["Курс высшей алгебры"](vilenin.narod.ru/Mm/Books/65/book65_1.pdf)
- [Определитель](https://ru.wikipedia.org/wiki/%D0%9E%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B8%D1%82%D0%B5%D0%BB%D1%8C) и [Метод Гаусса](https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%93%D0%B0%D1%83%D1%81%D1%81%D0%B0) на сайте Wikipedia

### Документация разработчика:

TBD

0 comments on commit 05b1ce2

Please sign in to comment.