TCS3200 Match
-
Upload
anonymous-ubalkko -
Category
Documents
-
view
216 -
download
0
Transcript of TCS3200 Match
-
8/17/2019 TCS3200 Match
1/9
############################################################################## ## TCS230/TCS3200/ColorPAL Color Match Software ## (C) Copyright 2006, 2009 Bueno Systems, Inc. ## Contact: [email protected] ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## ##############################################################################
use Win32::SerialPort qw(:STAT);use Win32::Registry;
use Tk;use Tk::Canvas;use Tk::Photo;use Tk::Scale;use Tk::Table;use Tk::DialogBox;use Tk::ROText;use Tk::ToggleButton;use File::Basename;
require Win32::API;require "utf8_heavy.pl";require "unicore/lib/SpacePer.pl";
require "unicore/To/Lower.pl";require "unicore/To/Upper.pl";require "unicore/To/Fold.pl";require "unicore/lib/Digit.pl";require "unicore/lib/Word.pl";require "Encode/Unicode.pm";
$CMD_OFF = chr(0x40);$CMD_RAW = chr(0x41);$CMD_BAL = chr(0x42);$CMD_PUT = chr(0x43);$CMD_GET = chr(0x44);
$DLE = chr(0x10);
my $Registry;$::HKEY_LOCAL_MACHINE->Open("HARDWARE\\DEVICEMAP\\SERIALCOMM", $Registry) or die "Can't open data: $^E";my @PortNames = ();
@RGB = ('#ff0000', '#00ff00', '#0000ff');@CurrentBlack = (0, 0, 0);
-
8/17/2019 TCS3200 Match
2/9
$mw = Tk::MainWindow->new(-title => 'TCS3200/TCS230/ColorPAL Color Match v2.02');
$fraTop = $mw->Frame->pack(-side => 'top');
$fraSwatchPanel = $fraTop->Frame(# -background => LIGHTGRAY,
-height => 256,-width => 128,
)->pack(-side => 'left');
$txtMsg = $fraSwatchPanel->Label(-background => BLACK,-foreground => YELLOW,-textvariable => \$Message,-relief => 'sunken',-borderwidth => 2
)->pack(-side => 'top', -expand => 1, -fill => 'x', -padx => 2, -pady => 2);
$fraWB = $fraSwatchPanel->Frame()->pack(-side => 'top');
foreach (0..1) {$btnWB[$_] = $fraWB->ToggleButton(
-width => 10,
-text => $_ ? 'Balanced' : 'Raw',-ontrigger => 'press',-latching => 1,-togglegroup => \@btnWB,-onbackground => CYAN,-onaltbackground => YELLOW,-onaltforeground => RED,-command => \&PressWB,-index => $_
)->pack(-side => 'left');}
$fraWB = $fraSwatchPanel->Frame()->pack(-side => 'top');
$fraWB->ToggleButton(-offforeground => 'WHITE',-offbackground => '#999999',-width => 10,-text => 'Set White',-command => \&DoWhiteBalance
)->pack(-side => 'left', -pady => 2);
$fraWB->ToggleButton(-offforeground => 'BLACK',-offbackground => '#999999',-width => 10,
-text => 'Set Black',-command => \&DoBlackBalance
)->pack(-side => 'left', -pady => 2);
$canBars = $fraSwatchPanel->Canvas(-background => BLACK,-width => 124,-height => 54,-relief => 'sunken',-borderwidth => 2
-
8/17/2019 TCS3200 Match
3/9
)->pack(-side => 'top', -pady => 2);
foreach (0..2) {$canBar[$_] = $canBars->createRectangle(
0, $_ * 18 + 4, -128, $_ * 18 + 21,-fill => $RGB[$_]
);$txtBar[$_] = $canBars->createText(
65,$_ * 18 + 13,-text => '',-font => 'Arial 11 bold',-fill => WHITE,-justify => 'right'
)}
$fraSwatch = $fraSwatchPanel->Frame(-background => BLACK,-height => 40,-width => 128,-relief => 'sunken',-borderwidth => 2,
)->pack(-side => 'top');
$fraSwatchPanel->Scale(-orient => 'horizontal',-label => 'Gamma Correction',-length => 128,-width => 15,-sliderlength => 15,-from => 1,-to => 100,-troughcolor => BLACK,-variable => \$CurrentGamma,-command => \&SetGamma
)->pack(-side => 'top');
$CurrentGamma = 35;
$fraSwatchPanel->Label(-text => "©Copyright 2002, 2009\nBueno Systems, Inc.",
)->pack;
$fraButtons = $fraTop->Frame(-width => 260,-height => 260
)->pack(-side => 'left');
foreach my $y (0..9) {foreach my $x (0..9) {
my $i = $y * 10 + $x;$lblColor[$i] = $fraButtons->Label(
-takefocus => 1,-relief => 'raised',-borderwidth => 1,-text => $i,
)->place(-x => $x * 26, -y => $y * 26, -width => 26, -height =>26);
$lblColor[$i]->bind('' => eval("sub {DefineColor($i, ".'@CurrentRGB)}'));
-
8/17/2019 TCS3200 Match
4/9
$lblColor[$i]->bind('' => eval("sub {UndefineColor($i)}"));
}}
$fraBot = $mw->Frame->pack(-side => 'top');
$canDist = $fraBot->Canvas(-background => BLACK,-height => 210,-width => 390
)->pack;
foreach (0..99) {$txtDist[$_] = $canDist->createText(
500, 0,-text => $_,-fill => WHITE,-font => 'Arial 7 bold',-justify => 'right'
)}
$mw->update;
OpenPort();
$Message = '';$UpdateID = $mw->repeat(50, \&Update);$mw->repeat(250, \&FlashSelected);$btnWB[0]->TurnOn;MainLoop();
sub OpenPort {my %coms;$Registry->GetValues(\%coms);@PortNames = grep {m/^COM\d+$/} (map {$coms{$_}->[2]} keys %coms);
foreach my $dev ((@PortNames) x 2, undef) {unless (defined $dev) {$mw->messageBox(
-title => 'Serial I/O Error',-message => 'Unable to locate color sensor outpu
t on any serial port.',-type => 'OK'
);exit
}$Message = "Scanning $dev.";$txtMsg->update;
unless ($Port = new Win32::SerialPort("\\\\.\\$dev")and $Port->baudrate(9600)and $Port->parity('none')and $Port->databits(8)and $Port->stopbits(2)and $Port->buffers(4096,4096)and $Port->binary(1)and $Port->write_settings)
{next
-
8/17/2019 TCS3200 Match
5/9
}Win32::Sleep 1000;my (undef, $n, undef, $err) = ($Port->status);if ($err) {
$Port->reset_error;}if ($n) {
my $stream = $Port->input;last if $stream =~ m/R\d+ G\d+ B\d+\r/
}$Port->close
}return
}
sub Update {my $nxt;$Port->error_msg(1);my (undef, $n, undef, $err) = ($Port->status);if ($err) {
$Port->reset_error;}if ($n) {
$QuiteTimes = 0;
$stream .= $Port->input;while ($stream =~ m/(R\d+ G\d+ B\d+)\r/osg) {$lastRGB = $1;$nxt = pos($stream);
}$stream = substr($stream, $nxt) if defined $nxt;if ($lastRGB && defined $WBMode) {
@color = ($lastRGB =~ m/R(\d+) G(\d+) B(\d+)/);@CurrentRaw = @color;if ($WBMode eq $CMD_BAL && defined @CurrentWhite && defi
ned @CurrentBlack) {@CurrentRGB = map {int(($CurrentRaw[$_] - $Curre
ntBlack[$_]) * 255 / ($CurrentWhite[$_] - $CurrentBlack[$_]))} (0 .. 2)
} else {@CurrentRGB = @CurrentRaw}my $status = grep {$_ > 255} @CurrentRGB;$Message = $status ? 'Saturated' : '';foreach my $i (0..2) {
$canBars->itemconfigure($txtBar[$i], -text => $CurrentRGB[$i]);
$canBars->coords($canBar[$i], 0, $i * 18 + 4, $CurrentRGB[$i] / 2, $i * 18 + 21)
}@CurrentRGB = map {$_ > 255 ? 255 : $_} @CurrentRGB;$fraSwatch->configure(-background => ScreenColor(@Curren
tRGB));&BestMatch
}} else {
PutMsg($WBMode) if $QuiteTimes++ > 30}
}
sub PutMsg {PutCmd(shift);
-
8/17/2019 TCS3200 Match
6/9
map {PutDat(chr($_))} @_;}
sub PutCmd {$Port->write($DLE.$_[0]);
}
sub PutDat {my $parm = $_[0];if ($parm eq $DLE) {
$Port->write($DLE.$DLE);} else {
$Port->write($parm);}
}
sub SetGamma {foreach (grep defined, @DefinedColor) {
my ($n, @rgb) = @$_;$lblColor[$n]->configure(-background => ScreenColor(@rgb))
}}
sub ScreenColor {
my @rgb = GammaCorrect(@_);do {$rgb[$_] = 0 if $rgb[$_] < 0} foreach (0 .. 2);return sprintf('#%2.2X%2.2X%2.2X', @rgb)
}
sub GammaCorrect {my $max = (sort {$b $a} @_)[0];my $gammaf = ($max / 255) ** ($CurrentGamma / 100) * 255 / ($max or 1);return map {$gammaf * $_} @_
}
sub RGBtoYCC {my @rgb = map {$_ / 255} @_;
my ($r, $g, $b) = @rgb;my $y = 0.299 * $r + 0.587 * $g + 0.114 * $b;my $c1 = $b - $y;my $c2 = $r - $y;$y = int(255 * $y);$c1 = int(111.40 * $c1) + 156;$c2 = int(135.64 * $c2) + 137;return ($y, $c1, $c2)
}
sub RGBtoYUV {my @rgb = @_;my ($r, $g, $b) = @_;
my $y = int(0.299 * $r + 0.587 * $g + 0.144 * $b);my $u = int(0.492 * ($b - $y) * 128 / 112 + 128);my $v = int(0.877 * ($r - $y) * 128 / 157 + 128);return ($y, $u, $v)
}
sub DefineColor {if ($WBMode eq $CMD_RAW) {
$mw->messageBox(-message => "Can't assign a raw color. Use 'Balanced' mode.", -type => 'ok')
-
8/17/2019 TCS3200 Match
7/9
} else {my $no = shift;my @rgb = @_;$lblColor[$no]->configure(
-relief => 'sunken',-background => ScreenColor(@rgb),
);$DefinedColor[$no] = [$no, @rgb];&BestMatch
}}
sub UndefineColor {my $no = shift;$lblColor[$no]->configure(-relief => 'raised', -background => GRAY);$canDist->coords($txtDist[$no], 500,0);undef $DefinedColor[$no];&BestMatch;
}
sub FlashSelected {if (defined $PrevSelected) {
$lblColor[$PrevSelected]->configure(-foreground => BLACK);}
if (defined $Selected) {$lblColor[$Selected]->configure(-foreground => $Flash ? BLACK :YELLOW);
$Flash = not $Flash;}$PrevSelected = $Selected
}
sub BestMatch {my $nBest;my $distBest = 1e38;my @Defined = grep defined, @DefinedColor;foreach (@Defined) {
my ($n, @rgb) = @$_;my $distMax = 0;foreach my $i (0..2) {
$dist = abs($rgb[$i] - $CurrentRGB[$i]);$distMax = $dist if $dist > $distMax
}$canDist->coords($txtDist[$n], $distMax * 2 + 10, $n * 2 + 10);if ($distMax < $distBest) {$nBest = $n; $distBest = $distMax}
}return $Selected = $nBest
}
sub PressWB {
my ($on, $i) = @_;if ($on) {
if ($i && !defined @CurrentWhite) {$mw->messageBox(-message => '"White" is undefined. Set w
hite first.', -type => 'ok');$btnWB[0]->TurnOn;return
} elsif ($i && !defined @CurrentBlack) {$mw->messageBox(-message => '"Black" is undefined. Set b
lack first.', -type => 'ok');
-
8/17/2019 TCS3200 Match
8/9
$btnWB[0]->TurnOn;return
}$WBMode = $i ? $CMD_BAL : $CMD_RAW
}}
sub DoWhiteBalance {@CurrentWhite = @CurrentRaw;$btnWB[1]->TurnOn if defined @CurrentBlack
}
sub DoBlackBalance {@CurrentBlack = @CurrentRaw;$btnWB[1]->TurnOn if defined @CurrentWhite
}
sub StoreColors {PutMsg($CMD_OFF);$mw->afterCancel($UpdateID);$Message = '';$txtMsg->update;foreach my $no (0..99) {
if (defined $DefinedColor[$no]) {
PutMsg($CMD_PUT, 0x80 + $no, @{$DefinedColor[$no]}[1..3]);} else {
PutMsg($CMD_PUT, $no, 0, 0, 0)}my $c;do {
$c = $Port->input} until $c =~ m/\x43/;if ($no & 1) {
$Message .= '|';$txtMsg->update
}
}PutMsg($WBMode);$UpdateID = $mw->repeat(50, \&Update);
# $Message = ''}
sub RetrieveColors {PutMsg($CMD_OFF);$mw->afterCancel($UpdateID);$Message = '';$txtMsg->update;foreach my $no (0..99) {
PutMsg($CMD_GET, $no);
my $c = '';do {
$c .= $Port->input} until $c =~ m/\x10\x44(((\x10\x10)|[^\x10]){4})/;$c = $1;$c =~ s/\x10\x10/\x10/;my ($def, @rgb) = map ord, split(//, $c);if ($def & 0x80) {
DefineColor($no, @rgb);} else {
-
8/17/2019 TCS3200 Match
9/9
UndefineColor($no)}if ($no & 1) {
$Message .= '|';$txtMsg->update
}}PutMsg($WBMode);$UpdateID = $mw->repeat(50, \&Update);
}