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 )