AssoriumHabr├й рдкрд░ рдХрдИ рд▓реЗрдЦреЛрдВ рдХреЛ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдФрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛: рдЫрд╡рд┐ рдореЗрдВ рдкреНрд░рдореБрдЦ рд░рдВрдЧ рдЪреБрдирдиреЗ рдХреЗ рд▓рд┐рдП:
1 ,
2 ,
3 ред рдЙрди рд▓реЗрдЦреЛрдВ рдХреА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ, рдЖрдк рдПрдХ рджрд░реНрдЬрди рд╕рдорд╛рди рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдФрд░ рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд▓рд┐рдВрдХ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдкреВрд░реНрдгрддрд╛ рдХреА рдХреЛрдИ рд╕реАрдорд╛ рдирд╣реАрдВ рд╣реИ - рдФрд░ рд╕рдмрд╕реЗ рдЗрд╖реНрдЯрддрдо рдкреНрд░рддреАрдд рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдкрджреНрдзрддрд┐ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ? рд╣рдо k- рд╕рд╛рдзрди рд╡рд┐рдзрд┐ (k- рд╕рд╛рдзрди) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреНрд▓рд╕реНрдЯрд░рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВред
рдЙрдирдХреЗ рдкрд╣рд▓реЗ рдХреЗ рдХрдИ рд▓реЛрдЧреЛрдВ рдХреА рддрд░рд╣, рдЕрдореЗрд░рд┐рдХреА рд╡реЗрдм рдбреЗрд╡рд▓рдкрд░ рдЪрд╛рд░реНрд▓реНрд╕ рд▓реЗрдЗрдлрд╝рд░ рдиреЗ рдЫрд╡рд┐ рдореЗрдВ рд░рдВрдЧреЛрдВ рдХреЛ рдХреНрд▓рд╕реНрдЯрд░ рдХрд░рдиреЗ рдХреЗ
рд▓рд┐рдП k- рд╕рд╛рдзрди рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред рдХрд┐рд╕реА рднреА рдбреЗрдЯрд╛ рдХреЛ рдХреНрд▓рд╕реНрдЯрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдзрд┐ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдЗрди рд╕рдореВрд╣реЛрдВ рдХреЗ рдХреЗрдВрджреНрд░реЛрдВ рд╕реЗ рд╕рдореВрд╣реЛрдВ рдХреЗ рдмрд┐рдВрджреБрдУрдВ рдХреЗ рдХреБрд▓ рджреНрд╡рд┐рдШрд╛рдд рд╡рд┐рдЪрд▓рди рдХреЛ рдХрдо рдХрд░рдирд╛ рд╣реИред рдкрд╣рд▓реЗ рдЪрд░рдг рдореЗрдВ, рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдмрд┐рдВрджреБрдУрдВ (рджреНрд░рд╡реНрдпрдорд╛рди рдХреЗ рдХреЗрдВрджреНрд░) рдХреЛ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд░реВрдк рд╕реЗ рдЪреБрдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХреЗ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдХреЗрдВрджреНрд░ рд╕реЗ рд╕рдВрдмрджреНрдзрддрд╛ рдХреА рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИред рдлрд┐рд░, рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдкрд░, рджреНрд░рд╡реНрдпрдорд╛рди рдХреЗ рдХреЗрдВрджреНрд░реЛрдВ рдХрд╛ рдкреБрдирд░реНрдЧрдгрдирд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдЬрдм рддрдХ рдХрд┐ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ред
рдкрд░рд┐рдгрд╛рдо рдХреБрдЫ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИред рдЕрдВрдХ рд░рдВрдЧреАрди рд╣реЛрддреЗ рд╣реИрдВ, рдХреНрд▓рд╕реНрдЯрд░ рдХреЗ рд░рдВрдЧ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдХрд╛рд▓реЗ рдмрд┐рдВрджреБ рджреНрд░рд╡реНрдпрдорд╛рди рдХреЗ рдХреЗрдВрджреНрд░реЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреЗ рд╣реИрдВред

рдЬреИрд╕рд╛ рдХрд┐ рдЫрд╡рд┐рдпреЛрдВ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИ, рдкреНрд░рддреНрдпреЗрдХ рдкрд┐рдХреНрд╕реЗрд▓ рдХреЛ рддреАрди-рдЖрдпрд╛рдореА рдЖрд░рдЬреАрдмреА рдЕрдВрддрд░рд┐рдХреНрд╖ рдореЗрдВ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рджреНрд░рд╡реНрдпрдорд╛рди рдХреЗ рдХреЗрдВрджреНрд░реЛрдВ рдХреА рджреВрд░реА рдХреА рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИред рдЕрдиреБрдХреВрд▓рди рдХреЗ рд▓рд┐рдП, рдЫрд╡рд┐рдпреЛрдВ рдХреЛ
рдкреАрдЖрдИрдПрд▓ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ 200x200 рддрдХ рдШрдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ RGB рдорд╛рди рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдХреЛрдб
from collections import namedtuple from math import sqrt import random try: import Image except ImportError: from PIL import Image Point = namedtuple('Point', ('coords', 'n', 'ct')) Cluster = namedtuple('Cluster', ('points', 'center', 'n')) def get_points(img): points = [] w, h = img.size for count, color in img.getcolors(w * h): points.append(Point(color, 3, count)) return points rtoh = lambda rgb: '#%s' % ''.join(('%02x' % p for p in rgb)) def colorz(filename, n=3): img = Image.open(filename) img.thumbnail((200, 200)) w, h = img.size points = get_points(img) clusters = kmeans(points, n, 1) rgbs = [map(int, c.center.coords) for c in clusters] return map(rtoh, rgbs) def euclidean(p1, p2): return sqrt(sum([ (p1.coords[i] - p2.coords[i]) ** 2 for i in range(p1.n) ])) def calculate_center(points, n): vals = [0.0 for i in range(n)] plen = 0 for p in points: plen += p.ct for i in range(n): vals[i] += (p.coords[i] * p.ct) return Point([(v / plen) for v in vals], n, 1) def kmeans(points, k, min_diff): clusters = [Cluster([p], p, pn) for p in random.sample(points, k)] while 1: plists = [[] for i in range(k)] for p in points: smallest_distance = float('Inf') for i in range(k): distance = euclidean(p, clusters[i].center) if distance < smallest_distance: smallest_distance = distance idx = i plists[idx].append(p) diff = 0 for i in range(k): old = clusters[i] center = calculate_center(plists[i], old.n) new = Cluster(plists[i], center, old.n) clusters[i] = new diff = max(diff, euclidean(old.center, new.center)) if diff < min_diff: break return clusters
рдЙрджрд╛рд╣рд░рдг








рдкреНрд░рдореБрдЦ рд░рдВрдЧреЛрдВ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рдирд╛ рдПрдХ рдмрд╣реБрдд рд╣реА рдЙрдкрдпреЛрдЧреА рдЪреАрдЬ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдореЗрд╢рд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдПрдХ рд╡реЗрдмрд╕рд╛рдЗрдЯ рдпрд╛ рдХреБрдЫ рдпреВрдЖрдИ рддрддреНрд╡реЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреИрд▓реЗрдЯ рд╡рд┐рдХрд▓реНрдк рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреНрд░реЛрдо рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдлрд╝реЗрд╡рд┐рдХреЙрди рд╕реЗ рдкреНрд░рдореБрдЦ рд░рдВрдЧ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП k- рд╕рд╛рдзрди рд╡рд┐рдзрд┐
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
