Created
September 25, 2017 22:16
-
-
Save sjaveed/e4686cd65a4d86fb267173cdc78074f1 to your computer and use it in GitHub Desktop.
Clustering Colors using Affinity Propagation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'bundler/setup' | |
require 'affinity_propagation' | |
require 'byebug' | |
module AffinityPropagation | |
class Calculator | |
attr_accessor :availabilities, :responsibilities, :similarities | |
end | |
end | |
def yuv_distance(datum, exemplar) | |
r_mean = (datum[:r] + exemplar[:r]) / 2 | |
r_delta = datum[:r] - exemplar[:r] | |
g_delta = datum[:g] - exemplar[:g] | |
b_delta = datum[:b] - exemplar[:b] | |
(2 + r_mean / 256) * (r_delta ** 2) + 4 * (g_delta ** 2) + (2 + (255 - r_mean) / 256) * (b_delta ** 2) | |
end | |
def rgb_distance(datum, exemplar) | |
r_delta = datum[:r] - exemplar[:r] | |
g_delta = datum[:g] - exemplar[:g] | |
b_delta = datum[:b] - exemplar[:b] | |
(r_delta ** 2) + (g_delta ** 2) + (b_delta ** 2) | |
end | |
def uv_distance(datum, exemplar) | |
u_delta = datum[:u] - exemplar[:u] | |
v_delta = datum[:v] - exemplar[:v] | |
(u_delta ** 2) + (v_delta ** 2) | |
end | |
def rgb_output(datum) | |
[datum[:r], datum[:g], datum[:b]].join(' ') | |
end | |
def uv_output(datum) | |
[datum[:u], datum[:v]].join(' ') | |
end | |
html_colors = [] | |
File.open("html-colors.dat", "w") do |all_colors_file| | |
File.open("selected-html-color-codes.txt").each.map do |line| | |
next if line =~ /^\s*$/ # skip blank lines | |
next if line =~ /^#/ # skip comments | |
name, color, family = line.chomp.split(',') | |
r, g, b = color.gsub(/(.{2})(.{2})(.{2})/, '\1,\2,\3').split(',').map { |c| c.to_i(16) } | |
y = r * 0.299000 + g * 0.587000 + b * 0.114000 | |
u = r * -0.168736 + g * -0.331264 + b * 0.500000 + 128 | |
v = r * 0.500000 + g * -0.418688 + b * -0.081312 + 128 | |
datum = { | |
name: name, | |
family: family, | |
r: r, | |
g: g, | |
b: b, | |
y: y, | |
u: u, | |
v: v | |
} | |
all_colors_file << uv_output(datum) | |
all_colors_file << "\n" | |
html_colors << datum | |
end | |
end | |
apc = AffinityPropagation::Calculator.new(html_colors, lambda: 0.75) do |datum, exemplar| | |
# distance = rgb_distance(datum, exemplar) | |
# distance = yuv_distance(datum, exemplar) | |
distance = uv_distance(datum, exemplar) | |
-distance | |
end | |
apc.run(iterations: 10_000, stable_iterations: 50) do |iteration, stable_iterations| | |
clusters = apc.clusters | |
puts "Iterations: #{apc.total_iterations} - Stable: #{apc.stable_cluster_iterations} - Found #{clusters.size} clusters" | |
File.open('clustered-html-colors.dat', 'w') do |file| | |
clusters.each do |cluster| | |
exemplar = cluster[:exemplar] | |
file << uv_output(exemplar) | |
file << "\n" | |
end | |
end | |
`gnuplot -e 'set title "Iter: #{apc.total_iterations}, Stable: #{apc.stable_cluster_iterations}, Found: #{clusters.size}"' clusters.gnuplot > scatter.#{"%05d" % apc.total_iterations}.png` | |
end | |
clusters = apc.clusters | |
clusters.each do |cluster| | |
exemplar = cluster[:exemplar] | |
puts "#{exemplar[:name]} (#{exemplar[:family]})" | |
cluster[:members].each do |member| | |
puts " #{member[:name]} (#{member[:family]})" | |
end | |
end | |
puts | |
puts "Availability Matrix:" | |
puts apc.availabilities | |
puts | |
puts "Responsibility Matrix:" | |
puts apc.responsibilities |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# set terminal pngcairo transparent enhanced font "arial,10" fontscale 1.0 size 600, 400 | |
set terminal png | |
set dummy u, v | |
set key fixed right top vertical Right noreverse enhanced autotitle box lt black linewidth 1.000 dashtype solid | |
# set parametric | |
## set title "Clustering Colors in UV-space" | |
set xlabel "Chrominance (U)" | |
set ylabel "Chrominance (V)" | |
DEBUG_TERM_HTIC = 119 | |
DEBUG_TERM_VTIC = 119 | |
## Last datafile plotted: "html-colors.dat" | |
plot "html-colors.dat" title "Actual Colors", "clustered-html-colors.dat" title "Clusters" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Red Colors | |
IndianRed,CD5C5C,Red | |
LightCoral,F08080,Red | |
Salmon,FA8072,Red | |
DarkSalmon,E9967A,Red | |
LightSalmon,FFA07A,Red | |
Crimson,DC143C,Red | |
Red,FF0000,Red | |
FireBrick,B22222,Red | |
DarkRed,8B0000,Red | |
# Pink Colors | |
Pink,FFC0CB,Pink | |
LightPink,FFB6C1,Pink | |
HotPink,FF69B4,Pink | |
DeepPink,FF1493,Pink | |
MediumVioletRed,C71585,Pink | |
PaleVioletRed,DB7093,Pink | |
# Orange Colors | |
LightSalmon,FFA07A,Orange | |
Coral,FF7F50,Orange | |
Tomato,FF6347,Orange | |
OrangeRed,FF4500,Orange | |
DarkOrange,FF8C00,Orange | |
Orange,FFA500,Orange | |
# Yellow Colors | |
Gold,FFD700,Yellow | |
Yellow,FFFF00,Yellow | |
LightYellow,FFFFE0,Yellow | |
LemonChiffon,FFFACD,Yellow | |
LightGoldenrodYellow,FAFAD2,Yellow | |
PapayaWhip,FFEFD5,Yellow | |
Moccasin,FFE4B5,Yellow | |
PeachPuff,FFDAB9,Yellow | |
PaleGoldenrod,EEE8AA,Yellow | |
Khaki,F0E68C,Yellow | |
DarkKhaki,BDB76B,Yellow | |
# Purple Colors | |
Lavender,E6E6FA,Purple | |
Thistle,D8BFD8,Purple | |
Plum,DDA0DD,Purple | |
Violet,EE82EE,Purple | |
Orchid,DA70D6,Purple | |
Fuchsia,FF00FF,Purple | |
Magenta,FF00FF,Purple | |
MediumOrchid,BA55D3,Purple | |
MediumPurple,9370DB,Purple | |
Amethyst,9966CC,Purple | |
BlueViolet,8A2BE2,Purple | |
DarkViolet,9400D3,Purple | |
DarkOrchid,9932CC,Purple | |
DarkMagenta,8B008B,Purple | |
Purple,800080,Purple | |
Indigo,4B0082,Purple | |
SlateBlue,6A5ACD,Purple | |
DarkSlateBlue,483D8B,Purple | |
MediumSlateBlue,7B68EE,Purple | |
# Green Colors | |
GreenYellow,ADFF2F,Green | |
Chartreuse,7FFF00,Green | |
LawnGreen,7CFC00,Green | |
Lime,00FF00,Green | |
LimeGreen,32CD32,Green | |
PaleGreen,98FB98,Green | |
LightGreen,90EE90,Green | |
MediumSpringGreen,00FA9A,Green | |
SpringGreen,00FF7F,Green | |
MediumSeaGreen,3CB371,Green | |
SeaGreen,2E8B57,Green | |
ForestGreen,228B22,Green | |
Green,008000,Green | |
DarkGreen,006400,Green | |
YellowGreen,9ACD32,Green | |
OliveDrab,6B8E23,Green | |
Olive,808000,Green | |
DarkOliveGreen,556B2F,Green | |
MediumAquamarine,66CDAA,Green | |
DarkSeaGreen,8FBC8F,Green | |
LightSeaGreen,20B2AA,Green | |
DarkCyan,008B8B,Green | |
Teal,008080,Green |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment