File Coverage

blib/lib/PDL/ImageRGB.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             #
2             # GENERATED WITH PDL::PP from lib/PDL/ImageRGB.pd! Don't modify!
3             #
4             package PDL::ImageRGB;
5              
6             our @EXPORT_OK = qw(interlrgb rgbtogr bytescl cquant cquant_c );
7             our %EXPORT_TAGS = (Func=>\@EXPORT_OK);
8              
9 15     15   656 use PDL::Core;
  15         32  
  15         104  
10 15     15   123 use PDL::Exporter;
  15         35  
  15         124  
11 15     15   78 use DynaLoader;
  15         30  
  15         5781  
12              
13              
14            
15             our @ISA = ( 'PDL::Exporter','DynaLoader' );
16             push @PDL::Core::PP, __PACKAGE__;
17             bootstrap PDL::ImageRGB ;
18              
19              
20              
21              
22              
23              
24              
25              
26             #line 14 "lib/PDL/ImageRGB.pd"
27              
28             use strict;
29             use warnings;
30              
31             =head1 NAME
32              
33             PDL::ImageRGB -- some utility functions for RGB image data handling
34              
35             =head1 DESCRIPTION
36              
37             Collection of a few commonly used routines involved in handling of RGB, palette
38             and grayscale images. Not much more than a start. Should be a good place to
39             exercise some of the broadcast/map/clump PP stuff.
40              
41             Other stuff that should/could go here:
42              
43             =over 3
44              
45             =item *
46             color space conversion
47              
48             =item *
49             common image filters
50              
51             =item *
52             image rebinning
53              
54             =back
55              
56             =head1 SYNOPSIS
57              
58             use PDL::ImageRGB;
59              
60             =cut
61              
62             use vars qw( $typecheck $EPS );
63              
64             use PDL::Core;
65             use PDL::Basic;
66             use PDL::Primitive;
67             use PDL::Types;
68              
69             use Carp;
70             use strict 'vars';
71              
72             $PDL::ImageRGB::EPS = 1e-7; # there is probably a more portable way
73              
74             =head1 FUNCTIONS
75              
76             =head2 cquant
77              
78             =for ref
79              
80             quantize and reduce colours in 8-bit images
81              
82             =for usage
83              
84             ($out, $lut) = cquant($image [,$ncols]);
85              
86             This function does color reduction for <=8bit displays and accepts 8bit RGB
87             and 8bit palette images. It does this through an interface to the ppm_quant
88             routine from the pbmplus package that implements the median cut routine which
89             intelligently selects the 'best' colors to represent your image on a <= 8bit
90             display (based on the median cut algorithm). Optional args: $ncols sets the
91             maximum nunmber of colours used for the output image (defaults to 256).
92             There are images where a different color
93             reduction scheme gives better results (it seems this is true for images
94             containing large areas with very smoothly changing colours).
95              
96             Returns a list containing the new palette image (type PDL_Byte) and the RGB
97             colormap.
98              
99             =cut
100              
101             # full broadcasting support intended
102             *cquant = \&PDL::cquant;
103             sub PDL::cquant {
104             barf 'Usage: ($out,$olut) = cquant($image[,$ncols])'
105             if $#_<0 || $#_>1;
106             my $image = shift;
107             my $ncols;
108             if ($#_ >= 0 ) { $ncols=shift; } else { $ncols = 256; };
109             my @Dims = $image->dims;
110             my ($out, $olut) = (null,null);
111              
112             barf "input must be byte (3,x,x)" if (@Dims < 2) || ($Dims[0] != 3)
113             || ($image->get_datatype != $PDL_B);
114             cquant_c($image,$out,$olut,$ncols);
115             return ($out,$olut);
116             }
117              
118             =head2 interlrgb
119              
120             =for ref
121              
122             Make an RGB image from a palette image and its lookup table.
123              
124             =for usage
125              
126             $rgb = $palette_im->interlrgb($lut)
127              
128             Input should be of an integer type and the lookup table (3,x,...). Will perform
129             the lookup for any N-dimensional input pdl (i.e. 0D, 1D, 2D, ...). Uses the
130             index command but will dataflow only if
131             the $lut ndarray has the dataflow_forward flag set (see L).
132              
133             =cut
134              
135             # interlace a palette image, input as 8bit-image, RGB-lut (3,x,..) to
136             # (R,G,B) format for each pixel in the image
137             # should already support broadcasting
138             *interlrgb=\&PDL::interlrgb;
139             sub PDL::interlrgb {
140             my ($pdl,$lut) = @_;
141             my $lut_fflows = $lut->fflows;
142             # for our purposes $lut should be (3,z) where z is the number
143             # of colours in the lut
144             barf "expecting (3,x) input" if ($lut->dims)[0] != 3;
145             # do the conversion as an implicitly broadcasted index lookup
146             my $res = $lut->transpose->index($pdl->dummy(0));
147             $res->sever if !$lut_fflows;
148             return $res;
149             }
150              
151             =head2 rgbtogr
152              
153             =for ref
154              
155             Converts an RGB image to a grey scale using standard transform
156              
157             =for usage
158              
159             $gr = $rgb->rgbtogr
160              
161             Performs a conversion of an RGB input image (3,x,....) to a
162             greyscale image (x,.....) using standard formula:
163              
164             Grey = 0.301 R + 0.586 G + 0.113 B
165              
166             =cut
167              
168             # convert interlaced rgb image to grayscale
169             # will convert any (3,...) dim pdl, i.e. also single lines,
170             # stacks of RGB images, etc since implicit broadcasting takes care of this
171             # should already support broadcasting
172             *rgbtogr = \&PDL::rgbtogr;
173             sub PDL::rgbtogr {
174             barf "Usage: \$im->rgbtogr" if $#_ < 0;
175             my $im = shift;
176             barf "rgbtogr: expecting RGB (3,...) input"
177             if (($im->dims)[0] != 3);
178              
179             my $type = $im->get_datatype;
180             my $rgb = float([77,150,29])/256; # vector for rgb conversion
181             my $oim = null; # flag PP we want it to allocate
182             inner($im,$rgb,$oim); # do the conversion as a broadcasted inner prod
183              
184             return $oim->convert($type); # convert back to original type
185             }
186              
187             =head2 bytescl
188              
189             =for ref
190              
191             Scales a pdl into a specified data range (default 0-255)
192              
193             =for usage
194              
195             $scale = $im->bytescl([$top])
196              
197             By default $top=255, otherwise you have to give the desired top value as an
198             argument to C. Normally C doesn't rescale data that fits
199             already in the bounds 0..$top (it only does the type conversion if required).
200             If you want to force it to rescale so that the max of the output is at $top and
201             the min at 0 you give a negative $top value to indicate this.
202              
203             =cut
204              
205             # scale any pdl linearly so that its data fits into the range
206             # 0<=x<=$ncols where $ncols<=255
207             # returns scaled data with type converted to byte
208             # doesn't rescale but just typecasts if data already fits into range, i.e.
209             # data ist not necessarily stretched to 0..$ncols
210             # needs some changes for full broadcasting support ?? (explicit broadcasting?)
211             *bytescl = \&PDL::bytescl;
212             sub PDL::bytescl {
213             barf 'Usage: bytescl $im[,$top]' if $#_ < 0;
214             my $pdl = shift;
215             my ($top,$force) = (255,0);
216             $top = shift if $#_ > -1;
217             if ($top < 0) { $force=1; $top *= -1; }
218             $top = 255 if $top > 255;
219              
220             print "bytescl: scaling from 0..$top\n" if $PDL::debug;
221             my ($max, $min);
222             $max = max $pdl;
223             $min = min $pdl;
224             return byte $pdl if ($min >= 0 && $max <= $top && !$force);
225              
226             # check for pathological cases
227             if (($max-$min) < $EPS) {
228             print "bytescl: pathological case\n" if $PDL::debug;
229             return byte $pdl
230             if (abs($max) < $EPS) || ($max >= 0 && $max <= $top);
231             return byte ($pdl/$max);
232             }
233              
234             my $type = $pdl->get_datatype > $PDL_F ? $PDL_D : $PDL_F;
235             return byte ($top*($pdl->convert($type)-$min)/($max-$min)+0.5);
236             }
237              
238             ;# Exit with OK status
239              
240             1;
241              
242             =head1 BUGS
243              
244             This package doesn't yet contain enough useful functions!
245              
246             =head1 AUTHOR
247              
248             Copyright 1997 Christian Soeller
249             All rights reserved. There is no warranty. You are allowed
250             to redistribute this software / documentation under certain
251             conditions. For details, see the file COPYING in the PDL
252             distribution. If this file is separated from the PDL distribution,
253             the copyright notice should be included in the file.
254              
255             =cut
256             #line 257 "lib/PDL/ImageRGB.pm"
257              
258             *cquant_c = \&PDL::cquant_c;
259              
260              
261              
262              
263              
264              
265              
266             # Exit with OK status
267              
268             1;