How to do a particular image manipulation

edit
 
Original
 
After processing

In the image shown here, notice that the wherever there isn't "something", there is a gray background. The darkness of this backgroung varies in the "y" direction. What I would like to do is take a samples of this varying background at any given y and subtract that value all the way across the image at that y. Did I explain that clearly? Notice down the right hand side there is a wide blank space just for this purpose of sampling the background.

Any idea how I can do this? I have GIMP but am not particularly skilled with it and I am not a programmer. The original images I want to process are relatively large tiffs, if that matters. Thanks!! ike9898 15:30, 30 March 2007 (UTC)




You could probably get a reasonably good result in the Gimp by applying a mask that was created with a vertical gradient. I thought it was a fun problem, so I wrote some code that does it with Perl. It's not fast, but it does seem to do what you want. You run it with:

 perl -w normalize.pl REFERENCE-COLUMN SOURCE-IMAGE

You can figure out the reference column (x-pixel) on which to normalize using the Gimp's measuring tool. The tool puts the resulting image (with a red line showing the reference column) in out-SOURCE-IMAGE. Here's an example output. Enjoy! --TotoBaggins 19:54, 29 March 2007 (UTC)

#!/usr/bin/perl -w

use Image::Magick;
use strict;

use constant MAX_COLOR => 0xFFFF;

my $err;

my $fname = shift() or die 'usage';
my $reference_column = shift() or die 'usage';

my $src = Image::Magick->new();
$err = $src->Read($fname);
die $err if $err;

my $height = $src->Get('height');
my $width = $src->Get('width');

my $dest = Image::Magick->new();
$err = $dest->Set(size => "${width}x$height");
$err = $dest->ReadImage('xc:white');
die $err if $err;

$" = ',';
my @colors = qw(R G B);
foreach my $y (0 .. $height)
{
    my @ref_pixel = split ',', $src->Get("pixel[$reference_column,$y]");
    foreach my $x (0 .. $width)
    {
        my @pixel = split ',', $src->Get("pixel[$x,$y]");
        foreach my $color (0 .. 2)
        {
            $pixel[$color] += (MAX_COLOR - $ref_pixel[$color]);
            $pixel[$color] = MAX_COLOR if $pixel[$color] > MAX_COLOR;
        }  
        $err = $dest->Set("pixel[$x,$y]" => "@pixel");
        die $err if $err;
    }
}
my $box_right  = $reference_column + 1;
$dest->Draw(stroke      => 'red',
            strokewidth => 1,
            primitive   => 'line',
            points      => "$box_right,0 $box_right,$height");


$err = $dest->Write("out-$fname");
die $err if $err;