127 lines
3.3 KiB
Perl
Executable File
127 lines
3.3 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
|
|
# implements some algorithms described in (the otherwise very bad)
|
|
# http://www.biocomputer.com/Thesis.html
|
|
|
|
# these are all simple 2x2 kernels, fast but relatively effective
|
|
|
|
use Gimp::Feature 'pdl';
|
|
use Gimp 1.098;
|
|
use Gimp::Fu;
|
|
use Gimp::Util;
|
|
use PDL::LiteF;
|
|
|
|
sub iterate {
|
|
my ($drawable,$message,$kernel)=@_;
|
|
|
|
Gimp->progress_init ($message);
|
|
|
|
my @bounds = $drawable->bounds;
|
|
my @off = $drawable->offsets;
|
|
$bounds[2]-- if $bounds[0]+$bounds[2] >= ($drawable->offsets)[0]+$drawable->width;
|
|
$bounds[3]-- if $bounds[1]+$bounds[3] >= ($drawable->offsets)[1]+$drawable->height;
|
|
{
|
|
my $src = new PixelRgn ($drawable,@bounds[0,1],$bounds[2]+1,$bounds[3]+1,0,0);
|
|
my $dst = new PixelRgn ($drawable,@bounds,1,1);
|
|
|
|
my $iter = Gimp->pixel_rgns_register ($dst);
|
|
my $area = $bounds[2]*$bounds[3];
|
|
my $progress = 0;
|
|
|
|
do {
|
|
my ($x,$y,$w,$h)=($dst->x,$dst->y,$dst->w,$dst->h);
|
|
$dst->data($kernel->($src->get_rect($x,$y,$w+1,$h+1)->convert(short)));
|
|
$progress += $w*$h/$area;
|
|
Gimp->progress_update ($progress);
|
|
} while (Gimp->pixel_rgns_process ($iter));
|
|
}
|
|
Gimp->progress_update (1);
|
|
|
|
$drawable->merge_shadow (1);
|
|
$drawable->update (@bounds);
|
|
|
|
();
|
|
}
|
|
|
|
register "blur_2x2",
|
|
"smooth (low pass filter) an image using a fast 2x2 kernel",
|
|
"Low-pass filtering (smoothing) using a fast 2x2 kernel",
|
|
"Marc Lehmann",
|
|
"Marc Lehmann <pcg\@goof.com>",
|
|
"19990725",
|
|
N_"<Image>/Filters/Blur/2x2 Blur",
|
|
"RGB*, GRAY*",
|
|
[],
|
|
sub {
|
|
my($image,$drawable)=@_;
|
|
|
|
iterate $drawable,
|
|
"2x2 smoothing...",
|
|
sub {
|
|
($_[0]->slice(":,0:-2,0:-2")+
|
|
$_[0]->slice(":,1:-1,0:-2")+
|
|
$_[0]->slice(":,1:-1,1:-1")+
|
|
$_[0]->slice(":,0:-2,1:-1"))>>2;
|
|
};
|
|
};
|
|
|
|
register "contrast_enhance_2x2",
|
|
"contrast enhance an image using a fast 2x2 kernel",
|
|
"Contrast Enhance an image using a fast 2x2 kernel",
|
|
"Marc Lehmann",
|
|
"Marc Lehmann <pcg\@goof.com>",
|
|
"19990725",
|
|
N_"<Image>/Filters/Enhance/2x2 Contrast Enhance",
|
|
"RGB*, GRAY*",
|
|
[],
|
|
sub {
|
|
my($image,$drawable)=@_;
|
|
|
|
iterate $drawable,
|
|
"2x2 contrast enhancing...",
|
|
sub {
|
|
my $T = $_[0]->slice(":,0:-2,0:-2");
|
|
my $D = $_[0]->slice(":,1:-1,1:-1");
|
|
|
|
(($T<<1)-$D)->clip(0,255);
|
|
};
|
|
};
|
|
|
|
register "edge_detect_2x2",
|
|
"detects edges in an image using a fast 2x2 kernel",
|
|
"Detect edges in the image using a 2x2 kernel. It is similar to Sobel, yet sharper (and lower quality).",
|
|
"Marc Lehmann",
|
|
"Marc Lehmann <pcg\@goof.com>",
|
|
"19990725",
|
|
N_"<Image>/Filters/Edge-Detect/2x2 Edge Detect",
|
|
"RGB*, GRAY*",
|
|
[],
|
|
sub {
|
|
my($image,$drawable)=@_;
|
|
|
|
iterate $drawable,
|
|
"2x2 cross gradient...",
|
|
sub {
|
|
my $T = $_[0]->slice(":,0:-2,0:-2");
|
|
my $R = $_[0]->slice(":,1:-1,0:-2");
|
|
my $D = $_[0]->slice(":,1:-1,1:-1");
|
|
|
|
abs(cat($T-$R,$T-$D))
|
|
->convert(byte)
|
|
->mv(3,0)
|
|
->maximum;
|
|
};
|
|
};
|
|
|
|
exit main;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|