Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorRokuz <r.kuznetsow@gmail.com>2017-11-20 14:45:55 +0300
committerDaria Volvenkova <d.volvenkova@corp.mail.ru>2017-11-21 14:32:39 +0300
commit86bfbd101b89651297868b72b1ded393ce2db1ab (patch)
tree3e48578946393f1c69374c64056b15131321a78d /tools
parent5f415ddb32feecb27b45b558b52b1e41c5518550 (diff)
Fixed color comparison
Diffstat (limited to 'tools')
-rw-r--r--tools/python/transit/transit_color_palette.py104
-rwxr-xr-xtools/python/transit/transit_graph_generator.py52
2 files changed, 146 insertions, 10 deletions
diff --git a/tools/python/transit/transit_color_palette.py b/tools/python/transit/transit_color_palette.py
index 054dfd92ae..df44ce69bf 100644
--- a/tools/python/transit/transit_color_palette.py
+++ b/tools/python/transit/transit_color_palette.py
@@ -1,3 +1,5 @@
+import math
+
def to_rgb(color_str):
if len(color_str) != 6:
return (0, 0, 0)
@@ -7,6 +9,90 @@ def to_rgb(color_str):
return (r, g, b)
+def blend_colors(rgb_array1, rgb_array2, k):
+ return (rgb_array1[0] * (1.0 - k) + rgb_array2[0] * k,
+ rgb_array1[1] * (1.0 - k) + rgb_array2[1] * k,
+ rgb_array1[2] * (1.0 - k) + rgb_array2[2] * k)
+
+
+def rgb_pivot(n):
+ result = n / 12.92
+ if n > 0.04045:
+ result = ((n + 0.055) / 1.055) ** 2.4
+ return result * 100.0;
+
+
+def to_xyz(rgb_array):
+ r = rgb_pivot(rgb_array[0] / 255.0);
+ g = rgb_pivot(rgb_array[1] / 255.0);
+ b = rgb_pivot(rgb_array[2] / 255.0);
+ return (r * 0.4124 + g * 0.3576 + b * 0.1805,
+ r * 0.2126 + g * 0.7152 + b * 0.0722,
+ r * 0.0193 + g * 0.1192 + b * 0.9505)
+
+
+#https://en.wikipedia.org/wiki/Lab_color_space#CIELAB
+def lab_pivot(n):
+ if n > 0.008856:
+ return n ** (1.0/3.0)
+ return (903.3 * n + 16.0) / 116.0
+
+
+def to_lab(rgb_array):
+ xyz = to_xyz(rgb_array)
+ x = lab_pivot(xyz[0] / 95.047)
+ y = lab_pivot(xyz[1] / 100.0)
+ z = lab_pivot(xyz[2] / 108.883)
+ l = 116.0 * y - 16.0
+ if l < 0.0:
+ l = 0.0
+ a = 500.0 * (x - y)
+ b = 200.0 * (y - z)
+ return (l, a, b)
+
+
+def lum_distance(ref_color, src_color):
+ return 30 * (ref_color[0] - src_color[0]) ** 2 +\
+ 59 * (ref_color[1] - src_color[1]) ** 2 +\
+ 11 * (ref_color[2] - src_color[2]) ** 2
+
+
+def is_bluish(rgb_array):
+ d1 = lum_distance((255, 0, 0), rgb_array)
+ d2 = lum_distance((0, 0, 255), rgb_array)
+ return d2 < d1
+
+
+#http://en.wikipedia.org/wiki/Color_difference#CIE94
+def cie94(ref_color, src_color):
+ lab_ref = to_lab(ref_color)
+ lab_src = to_lab(src_color)
+ deltaL = lab_ref[0] - lab_src[0]
+ deltaA = lab_ref[1] - lab_src[1]
+ deltaB = lab_ref[2] - lab_src[2]
+ c1 = math.sqrt(lab_ref[0] * lab_ref[0] + lab_ref[1] * lab_ref[1])
+ c2 = math.sqrt(lab_src[0] * lab_src[0] + lab_src[1] * lab_src[1])
+ deltaC = c1 - c2
+ deltaH = deltaA * deltaA + deltaB * deltaB - deltaC * deltaC
+ if deltaH < 0.0:
+ deltaH = 0.0
+ else:
+ deltaH = math.sqrt(deltaH)
+ # cold tones if a color is more bluish.
+ Kl = 1.0
+ K1 = 0.045
+ K2 = 0.015
+ sc = 1.0 + K1 * c1
+ sh = 1.0 + K2 * c1
+ deltaLKlsl = deltaL / Kl
+ deltaCkcsc = deltaC / sc
+ deltaHkhsh = deltaH / sh
+ i = deltaLKlsl * deltaLKlsl + deltaCkcsc * deltaCkcsc + deltaHkhsh * deltaHkhsh
+ if i < 0:
+ return 0.0
+ return math.sqrt(i)
+
+
class Palette:
def __init__(self, colors):
self.colors = {}
@@ -16,16 +102,26 @@ class Palette:
def get_default_color(self):
return 'default'
- def get_nearest_color(self, color_str):
+ def get_nearest_color(self, color_str, casing_color_str, excluded_names):
"""Returns the nearest color from the palette."""
nearest_color_name = self.get_default_color()
color = to_rgb(color_str)
+ if (casing_color_str is not None and len(casing_color_str) != 0):
+ color = blend_colors(color, to_rgb(casing_color_str), 0.5)
min_diff = None
+
+ bluish = is_bluish(color)
for name, palette_color in self.colors.iteritems():
- diff = 30 * (palette_color[0] - color[0]) ** 2 +\
- 59 * (palette_color[1] - color[1]) ** 2 +\
- 11 * (palette_color[2] - color[2]) ** 2
+ if name in excluded_names:
+ continue
+ if bluish:
+ diff = lum_distance(palette_color, color)
+ else:
+ diff = cie94(palette_color, color)
if min_diff is None or diff < min_diff:
min_diff = diff
nearest_color_name = name
+ # Left here for debug purposes.
+ #print("Result: " + color_str + "," + str(casing_color_str) +
+ # " - " + nearest_color_name + ": bluish = " + str(bluish))
return nearest_color_name
diff --git a/tools/python/transit/transit_graph_generator.py b/tools/python/transit/transit_graph_generator.py
index cc9e407474..acf6091416 100755
--- a/tools/python/transit/transit_graph_generator.py
+++ b/tools/python/transit/transit_graph_generator.py
@@ -6,6 +6,7 @@ import copy
import json
import math
import matplotlib.pyplot as plt
+import matplotlib.patches as patches
import numpy as np
import os.path
import sys, io
@@ -70,6 +71,7 @@ class TransitGraphBuilder:
self.segments = {}
self.shapes = []
self.transit_graph = None
+ self.matched_colors = {}
def __get_average_stops_point(self, stop_ids):
"""Returns an average position of the stops."""
@@ -176,10 +178,7 @@ class TransitGraphBuilder:
'interval': line_item['interval'],
'stop_ids': []
}
- if 'colour' in route_item:
- line['color'] = self.palette.get_nearest_color(route_item['colour'])
- else:
- line['color'] = self.palette.get_default_color()
+ line['color'] = self.__match_color(route_item.get('colour', ''), route_item.get('casing', ''))
# TODO: Add processing of line_item['shape'] when this data will be available.
# TODO: Add processing of line_item['trip_ids'] when this data will be available.
@@ -203,6 +202,17 @@ class TransitGraphBuilder:
self.lines.append(line)
line_index += 1
+ def __match_color(self, color_str, casing_str):
+ if len(color_str) == 0:
+ return self.palette.get_default_color()
+ matched_colors_key = color_str + "/" + casing_str
+ if matched_colors_key in self.matched_colors:
+ return self.matched_colors[matched_colors_key]
+ c = self.palette.get_nearest_color(color_str, casing_str, self.matched_colors.values())
+ if c != self.palette.get_default_color():
+ self.matched_colors[matched_colors_key] = c
+ return c
+
def __generate_transfer_nodes(self):
"""Merges stops into transfer nodes."""
for edge in self.edges:
@@ -332,6 +342,27 @@ class TransitGraphBuilder:
plt.scatter([point['x']], [point['y']], size, color)
plt.show()
+ def show_color_maching_table(self, title, colors_ref_table):
+ fig = plt.figure()
+ ax = fig.add_subplot(111, aspect='equal')
+ plt.title(title)
+ sz = 1.0 / (2.0 * len(self.matched_colors))
+ delta_y = sz * 0.5
+ for c in self.matched_colors:
+ tokens = c.split('/')
+ if len(tokens[1]) == 0:
+ tokens[1] = tokens[0]
+ ax.add_patch(patches.Rectangle((sz, delta_y), sz, sz, facecolor="#" + tokens[0], edgecolor="#" + tokens[1]))
+ rect_title = tokens[0]
+ if tokens[0] != tokens[1]:
+ rect_title += "/" + tokens[1]
+ ax.text(2.5 * sz, delta_y, rect_title + " -> ")
+ ref_color = colors_ref_table[self.matched_colors[c]]
+ ax.add_patch(patches.Rectangle((0.3 + sz, delta_y), sz, sz, facecolor="#" + ref_color))
+ ax.text(0.3 + 2.5 * sz, delta_y, ref_color + " (" + self.matched_colors[c] + ")")
+ delta_y += sz * 2.0
+ plt.show()
+
if __name__ == '__main__':
parser = argparse.ArgumentParser()
@@ -342,6 +373,9 @@ if __name__ == '__main__':
help='transit colors file COLORS_FILE_PATH', metavar='COLORS_FILE_PATH')
parser.add_argument('-p', '--preview', action="store_true", default=False,
help="show preview of the transit scheme")
+ parser.add_argument('-m', '--matched_colors', action="store_true", default=False,
+ help="show the matched colors table")
+
parser.add_argument('-a', '--alpha', type=float, default=0.5, help='the curves generator parameter value ALPHA',
metavar='ALPHA')
@@ -360,9 +394,9 @@ if __name__ == '__main__':
result = transit.build()
output_file = args.output_file
+ head, tail = os.path.split(os.path.abspath(args.input_file))
+ name, extension = os.path.splitext(tail)
if output_file is None:
- head, tail = os.path.split(os.path.abspath(args.input_file))
- name, extension = os.path.splitext(tail)
output_file = os.path.join(head, name + '.transit' + extension)
with io.open(output_file, 'w', encoding='utf8') as json_file:
result_data = json.dumps(result, ensure_ascii=False, indent=4, sort_keys=True)
@@ -371,3 +405,9 @@ if __name__ == '__main__':
if args.preview:
transit.show_preview()
+
+ if args.matched_colors:
+ colors_ref_table = {}
+ for color_name, color_info in colors['colors'].iteritems():
+ colors_ref_table[color_name] = color_info['clear']
+ transit.show_color_maching_table(name, colors_ref_table)