AI-MXNet

 view release on metacpan or  search on metacpan

lib/AI/MXNet/Image.pm  view on Meta::CPAN

package AI::MXNet::Image;
use strict;
use warnings;
use Scalar::Util qw(blessed);
use AI::MXNet::Base;
use AI::MXNet::Function::Parameters;

=head1 NAME

    AI::MXNet:Image - Read individual image files and perform augmentations.
=cut

=head2 imdecode

    Decode an image from string. Requires OpenCV to work.

    Parameters
    ----------
    $buf : str, array ref, pdl, ndarray
        Binary image data.
    :$flag : int
        0 for grayscale. 1 for colored.
    :$to_rgb : int
        0 for BGR format (OpenCV default). 1 for RGB format (MXNet default).
    :$out : NDArray
        Output buffer. Do not specify for automatic allocation.
=cut

method imdecode(Str|PDL $buf, Int :$flag=1, Int :$to_rgb=1, Maybe[AI::MXNet::NDArray] :$out=)
{
    if(not ref $buf)
    {
        my $pdl_type = PDL::Type->new(DTYPE_MX_TO_PDL->{'uint8'});
        my $len; { use bytes; $len = length $buf; }
        my $pdl = PDL->new_from_specification($pdl_type, $len);
        ${$pdl->get_dataref} = $buf;
        $pdl->upd_data;
        $buf = $pdl;
    }
    if(not (blessed $buf and $buf->isa('AI::MXNet::NDArray')))
    {
        $buf = AI::MXNet::NDArray->array($buf, dtype=>'uint8');
    }
    return AI::MXNet::NDArray->_cvimdecode($buf, { flag => $flag, to_rgb => $to_rgb, ($out ? (out => $out) : ()) });
}

=head2 scale_down

Scale down crop size if it's bigger than the image size.

    Parameters:
    -----------
    Shape $src_size
    Shape $size

    Returns:
    --------
    ($w, $h)
=cut

method scale_down(Shape $src_size, Shape $size)
{
    my ($w, $h) = @{ $size };
    my ($sw, $sh) = @{ $src_size };
    if($sh < $h)
    {
        ($w, $h) = (($w*$sh)/$h, $sh);
    }
    if($sw < $w)
    {
        ($w, $h) = ($sw, ($h*$sw)/$w);
    }
    return (int($w), int($h));
}

=head2 resize_short

    Resize shorter edge to the size.

    Parameters:
    -----------
    AI::MXNet::NDArray $src
    Int                $size
    Int                $interp=2

    Returns:
    --------
    AI::MXNet::NDArray $resized_image
=cut

method resize_short(AI::MXNet::NDArray $src, Int $size, Int $interp=2)
{
    my ($new_h, $new_w);
    my ($h, $w) = @{ $src->shape };
    if($h > $w)
    {
        ($new_h, $new_w) = ($size*$h/$w, $size);
    }
    else
    {
        ($new_h, $new_w) = ($size, $size*$w/$h);
    }

lib/AI/MXNet/Image.pm  view on Meta::CPAN

        $src += AI::MXNet::NDArray->array($rgb);
        return [$src]
    };
    return $aug
}

=head2 ColorNormalizeAug

    Makes "Mean and std normalization" closure.

    Parameters:
    -----------
    PDL $mean
    PDL $std

    Returns:
    --------
    CodeRef that accepts AI::MXNet::NDArray $src as input
    and returns [__PACKAGE__->color_normalize($src, $mean, $std)]
=cut

method ColorNormalizeAug(PDL $mean, PDL $std)
{
    $mean = AI::MXNet::NDArray->array($mean);
    $std = AI::MXNet::NDArray->array($std);
    my $aug = sub { my $src = shift;
        return [__PACKAGE__->color_normalize($src, $mean, $std)]
    };
    return $aug;
}

=head2 HorizontalFlipAug

    Makes "Random horizontal flipping" closure.

    Parameters:
    -----------
    Num $p < 1

    Returns:
    --------
    CodeRef that accepts AI::MXNet::NDArray $src as input
    and returns [$p > rand ? AI::MXNet::NDArray->flip($src, axis=1>) : $src]
=cut

method HorizontalFlipAug(Num $p)
{
    my $aug = sub { my $src = shift;
        return [$p > rand() ? AI::MXNet::NDArray->flip($src, { axis=>1 }) : $src]
    };
    return $aug;
}

=head2 CastAug

    Makes "Cast to float32" closure.

    Returns:
    --------
    CodeRef that accepts AI::MXNet::NDArray $src as input
    and returns [$src->astype('float32')]
=cut

method CastAug()
{
    my $aug = sub { my $src = shift;
        return [$src->astype('float32')]
    };
    return $aug;
}

=head2 CreateAugmenter

    Create augumenter list

    Parameters:
    -----------
    Shape          :$data_shape,
    Bool           :$resize=0,
    Bool           :$rand_crop=0,
    Bool           :$rand_resize=0,
    Bool           :$rand_mirror=0,
    Maybe[Num|PDL] :$mean=,
    Maybe[Num|PDL] :$std=,
    Num            :$brightness=0,
    Num            :$contrast=0,
    Num            :$saturation=0,
    Num            :$pca_noise=0,
    Int            :$inter_method=2
=cut

method CreateAugmenter(
Shape          :$data_shape,
Bool           :$resize=0,
Bool           :$rand_crop=0,
Bool           :$rand_resize=0,
Bool           :$rand_mirror=0,
Maybe[Num|PDL] :$mean=,
Maybe[Num|PDL] :$std=,
Num            :$brightness=0,
Num            :$contrast=0,
Num            :$saturation=0,
Num            :$pca_noise=0,
Int            :$inter_method=2
)
{
    my @auglist;
    if($resize > 0)
    {
        push @auglist, __PACKAGE__->ResizeAug($resize, $inter_method);
    }

    my $crop_size = [$data_shape->[2], $data_shape->[1]];
    if($rand_resize)
    {
        assert($rand_crop);
        push @auglist, __PACKAGE__->RandomSizedCropAug($crop_size, 0.3, [3.0/4.0, 4.0/3.0], $inter_method);
    }
    elsif($rand_crop)
    {
        push @auglist, __PACKAGE__->RandomCropAug($crop_size, $inter_method);
    }
    else
    {
        push @auglist, __PACKAGE__->CenterCropAug($crop_size, $inter_method);
    }



( run in 1.520 second using v1.01-cache-2.11-cpan-df04353d9ac )