PDLA
view release on metacpan or search on metacpan
Lib/Image2D/image2d.pd view on Meta::CPAN
=for ref
return the (dataflown) area of an image described by a polygon
=for usage
polyfillv($im,$ps,[\%options]);
The default method of determining which points lie inside of the polygon used
is not as strict as the method used in L<pnpoly|pnpoly>. Often, it includes vertices
and edge points. Set the C<Method> option to change this behaviour.
=for option
Method - Set the method used to determine which points lie in the polygon.
=> Default - internal PDLA algorithm
=> pnpoly - use the L<pnpoly|pnpoly> algorithm
=for example
# increment intensity in area bounded by $poly using the pnpoly algorithm
$im->polyfillv($poly,{'Method'=>'pnpoly'})++; # legal in perl >= 5.6
# compute average intensity within area bounded by $poly using the default algorithm
$av = $im->polyfillv($poly)->avg;
=cut
sub PDLA::polyfillv :lvalue {
my $opt;
$opt = pop @_ if ref($_[-1]) eq 'HASH';
barf('Usage: polyfillv($im,$ps,[\%options])') unless @_==2;
my ($im,$ps) = @_;
barf("ps must contain pairwise points.\n") unless $ps->getdim(0) == 2;
if($opt) {
use PDLA::Options qw();
my $parsed = PDLA::Options->new({'Method' => undef});
$parsed->options($opt);
return $im->where(PDLA::pnpoly_pp($im, $ps)) if $parsed->current->{'Method'} eq 'pnpoly';
}
my $msk = zeroes(long,$im->dims);
PDLA::polyfill_pp($msk, $ps, 1);
return $im->where($msk);
}
*polyfillv = \&PDLA::polyfillv;
EOPM
pp_addhdr('#include "rotate.c"'."\n\n");
pp_add_exported('','rotnewsz');
pp_addxs('
void
rotnewsz(m,n,angle)
int m
int n
float angle
PPCODE:
int newcols, newrows;
if (getnewsize(m,n,angle,&newcols,&newrows) != 0)
croak("wrong angle (should be between -90 and +90)");
EXTEND(sp,2);
PUSHs(sv_2mortal(newSVnv(newcols)));
PUSHs(sv_2mortal(newSVnv(newrows)));
');
pp_def('rot2d',
HandleBad => 0,
Pars => 'im(m,n); float angle(); bg(); int aa(); [o] om(p,q)',
Code => 'int ierr;
if ((ierr = rotate($P(im),$P(om),$SIZE(m),$SIZE(n),$SIZE(p),
$SIZE(q),$angle(),$bg(),$aa())) != 0) {
if (ierr == -1)
croak("error during rotate, wrong angle");
else
croak("wrong output dims, did you set them?");
}',
# ugly workaround since $SIZE(m) and $SIZE(n) are not initialized
# when the redodimscode is called
# need to fix this!
RedoDimsCode => 'int ncols, nrows;
if ($PDLA(im)->ndims < 2)
croak("need > 2d piddle");
if (getnewsize($PDLA(im)->dims[0],$PDLA(im)->dims[1],
$angle(), &ncols,
&nrows) != 0)
croak("error during rotate, wrong angle");
/* printf("o: %d, p: %d\n",ncols,nrows); */
$SIZE(p) = ncols;
$SIZE(q) = nrows;',
GenericTypes => ['B'],
Doc => << 'EOD',
=for ref
rotate an image by given C<angle>
=for example
# rotate by 10.5 degrees with antialiasing, set missing values to 7
$rot = $im->rot2d(10.5,7,1);
This function rotates an image through an C<angle> between -90 and + 90
degrees. Uses/doesn't use antialiasing depending on the C<aa> flag.
Pixels outside the rotated image are set to C<bg>.
Code modified from pnmrotate (Copyright Jef Poskanzer) with an algorithm based
on "A Fast Algorithm for General Raster Rotation" by Alan Paeth,
Graphics Interface '86, pp. 77-81.
Use the C<rotnewsz> function to find out about the dimension of the
newly created image
($newcols,$newrows) = rotnewsz $oldn, $oldm, $angle;
L<PDLA::Transform|PDLA::Transform> offers a more general interface to
distortions, including rotation, with various types of sampling; but
( run in 0.847 second using v1.01-cache-2.11-cpan-5511b514fd6 )