Skip to content

Instantly share code, notes, and snippets.

@sjaveed
Created September 25, 2017 22:16
Show Gist options
  • Save sjaveed/e4686cd65a4d86fb267173cdc78074f1 to your computer and use it in GitHub Desktop.
Save sjaveed/e4686cd65a4d86fb267173cdc78074f1 to your computer and use it in GitHub Desktop.
Clustering Colors using Affinity Propagation
#!/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
# 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"
# 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