PDL
view release on metacpan or search on metacpan
lib/PDL/Image2D.pd view on Meta::CPAN
=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>. 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 PDL algorithm
=> pnpoly - use the L</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 PDL::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 PDL::Options qw();
my $parsed = PDL::Options->new({'Method' => undef});
$parsed->options($opt);
return $im->where(PDL::pnpoly_pp($im, $ps)) if $parsed->current->{'Method'} eq 'pnpoly';
}
PDL::polyfill_pp(my $msk = zeroes(long,$im->dims), $ps, 1);
return $im->where($msk);
}
*polyfillv = \&PDL::polyfillv;
EOPM
pp_addhdr(<<'EOF');
int getnewsize(PDL_Indx cols, PDL_Indx rows, float fangle, PDL_Indx *newcols, PDL_Indx *newrows);
typedef unsigned char imT; /* image type */
int rotate(imT *im, imT *out, int cols, int rows, int nc, int nr,
float fangle, imT bgval, int antialias);
EOF
pp_add_exported('','rotnewsz');
pp_addxs('
void
rotnewsz(m,n,angle)
int m
int n
float angle
PPCODE:
PDL_Indx 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)',
GenericTypes => $A,
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?");
}',
RedoDimsCode => '
if (getnewsize($SIZE(m),$SIZE(n),
$angle(), &$SIZE(p),
&$SIZE(q)) != 0)
$CROAK("error during rotate, wrong angle");
/* printf("o: %d, p: %d\n",ncols,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<PDL::Transform> offers a more general interface to
distortions, including rotation, with various types of sampling; but
rot2d is faster.
=cut
EOD
( run in 1.055 second using v1.01-cache-2.11-cpan-5511b514fd6 )