#!/usr/local/bin/perl5 -w # # FuzzyColor - Turns RGB values into a textual decription # of the color via a fuzzifying algorithm # # REFERENCES: # # color conversion: # # http://www.cs.rit.edu/~ncs/color/t_convert.html # http://www.robo.mein.nagoya-u.ac.jp/~niimi/color-space/COL_25.htm # # # fuzzifier algorithm adapted from: # # C++ Neural Networks & Fuzzy Logic, 2nd Edition # by Dr. Valluru Rao and Hayagriva Rao # (c) 1995 MIS Press # ################################################################### use strict; use AI::Fuzzy::Set; use AI::Fuzzy::Label; use Color::Convert; my $hue = new AI::Fuzzy::Label; my $sat = new AI::Fuzzy::Label; my $val = new AI::Fuzzy::Label; ## first set up some labels ### $val->addlabel( "black", -1, 0, 15 ); $val->addlabel( "blackish", 10, 20, 30 ); $val->addlabel( "dark", 15, 30, 50 ); $val->addlabel( "normal", 40, 80, 95 ); $val->addlabel( "bright", 90, 100, 101 ); # very rare to say this $sat->addlabel( "gray", -1, 0, 20 ); $sat->addlabel( "pale", 15, 30, 72 ); $sat->addlabel( "normal", 60, 80, 101 ); $hue->addlabel( "gray", -2, -1, 0 ); $hue->addlabel( "red", -1, 0, 15 ); $hue->addlabel( "orange", 10, 30, 50 ); $hue->addlabel( "yellow", 45, 60, 75 ); $hue->addlabel( "green", 65, 120, 172 ); $hue->addlabel( "cyan", 165, 180, 190 ); $hue->addlabel( "blue", 180, 240, 260 ); $hue->addlabel( "indigo", 255, 260, 280 ); $hue->addlabel( "magenta", 270, 290, 310 ); $hue->addlabel( "violet", 300, 320, 340 ); $hue->addlabel( "red2", 330, 360, 361); ### get the color value from the command line ## ### possibly convert to hsv ## my ($h, $s, $v); @_ = @ARGV; SWITCH: for ($_[0]) { /rgb/i && do { shift @_; ($h, $s, $v) = rgb2hsv(@_); }; /\d+/ && do { ($h,$s,$v) = rgb2hsv(@_); }; /hsv/i && do { ($h, $s, $v) = @_; }; } ###### cfuzzify the color value ######### ## first, the hue ## my $hueset = new AI::Fuzzy::Set( $hue->label($h) ); my @colors = $hueset->members(); my $color = pop @colors; # if the color has more than one label, # pick one, or just merge them: if (@colors) { my $othercolor = pop (@colors); my $m_c = $hueset->membership($color); my $m_o = $hueset->membership($othercolor); # first, pick a "primary" label .. if ( rand( $m_o + $m_c ) > $m_c ) { ($color, $othercolor) = ($othercolor, $color); } # and if they're really close, pick both.. # (the 3 just gives othercolor a fighting chance) if ( rand() < (3 * $hueset->membership($othercolor))) { $color = $othercolor . "ish-" . $color; } } $color =~ s/red2/red/; $color =~ s/redish/reddish/; ## now the saturation ### for (my $saturation = $sat->label($s)) { m/gray/ && do { $color .= "ish gray" unless $color =~ /gray/; }; m/pale/ && do { $color = "pale $color"; }; } ## and the value... ## for (my $value = $val->label($v)) { m/black$/ && do { $color = "black"; }; m/blackish/ && do { $color .= "ish black" unless $color =~ s/.*ish gray/dark gray/; }; m/bright/ && do { $color = "bright $color" unless $color =~ s/gray$/white/; }; } ## now print it out ### print "$color\n"; __END__