package Blue; ########################################### # Mike Schilli, 2007 (m@perlmeister.com) ########################################### use Log::Log4perl qw(:easy); use strict; my $THRESHOLD = 50; use Imager; ########################################### sub detect { ########################################### my($img, $debug, $mindist) = @_; $mindist = 3 unless defined $mindist; LOGDIE "No image given" unless defined $img; my $i = Imager->new(); $i->read(file => $img, type => "jpeg") or LOGDIE "Can't read $img"; my @l = find_bound($i, "l", $THRESHOLD); my($lxfirst, $lyfirst) = @l; my $case; if($l[-2] > $l[0]) { $case = "A"; } else { $case = "B"; } INFO "Case: $case"; my @corners = (); my($xmin, $ymin); while(my($x, $y) = splice @l, 0, 2) { #print "L $x $y\n"; if(!defined $xmin or $x < $xmin - $mindist) { $xmin = $x; $ymin = $y; } } my @r = find_bound($i, "r", $THRESHOLD); my($rxfirst, $ryfirst) = @r; my($xmax, $ymax); while(my($x, $y) = splice @r, 0, 2) { if(!defined $xmax or $x > $xmax + $mindist) { $xmax = $x; $ymax = $y; } } if($case eq 'A') { #print "@l\n"; push @corners, [$lxfirst, $lyfirst]; push @corners, [$xmax, $ymax]; } else { push @corners, [$xmin, $ymin]; push @corners, [$rxfirst, $ryfirst]; } return @corners; } use Inline C => <<'EOT' => WITH => 'Imager'; #define MO_IV(x) sv_2mortal(newSViv(x)) #define IT_INIT(x,y,xs,ys,xd,yd) \ x = (xd > 0) ? 0 : xs -1; \ y = (yd > 0) ? 0 : ys -1; #define IT(x,y,xs,ys,xd,yd) \ x += xd; \ if(x >= xs || x < 0) { \ x = (xd > 0) ? 0 : xs -1; \ y += yd; \ } \ if(y >= ys || y < 0) { \ break; \ } #define IT_NEXT(x,y,xs,ys,xd,yd) \ x = (xd > 0) ? 0 : xs -1; \ y += yd; \ if(y >= ys || y < 0) { \ break; \ } void find_bound(Imager im, char direction, int thres) { int x, y; int br; int xd; if(direction == 'l') { xd = 1; } else { xd = -1; } Inline_Stack_Vars; Inline_Stack_Reset; IT_INIT(x, y, im->xsize, im->ysize, xd, 1); while(1) { br = blueness(im, x, y); if(br > thres) { Inline_Stack_Push(MO_IV(x)); Inline_Stack_Push(MO_IV(y)); IT_NEXT(x, y, im->xsize, im->ysize, xd, 1); continue; } IT(x, y, im->xsize, im->ysize, xd, 1); } Inline_Stack_Done; return; } int blueness(Imager im, int x, int y) { i_color val; int b; i_gpix(im, x, y, &val); b = val.channel[2] - val.channel[0] - val.channel[1]; return b; } EOT 1;