Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Perl Image Analysis

by Anonymous Monk
on Oct 04, 2006 at 19:02 UTC ( [id://576382]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Introduction

I am working with (physical) array data, that is scanned in at 100 microns / pixel. The result of this is a tif image with many spots corresponding to the points of interest on the array, which each have varied intensities. I have already figured out how to split these tif images into smaller files so that each point of interest is its own file. Now I am trying to figure out the next step - that is, I want to analyze each one independently. Each spot essentially has a "background" and a "data" region, that I could specify roughly by pixel locations.
I should also mention that there will be many of these arrays as time goes on, so I am looking of course for a reproducible method that I can repeat for any number of arrays as time goes on.

Question

Can I take these files into perl, and then do a comparison of the color (in this case, the greyscale value) of pixel (A,B) in the image versus (C,D) in the same image?

Replies are listed 'Best First'.
Re: Perl Image Analysis
by grep (Monsignor) on Oct 04, 2006 at 19:31 UTC
    I thought Image::Magick had a method to read a pixel color but, I could not find one. But GD does - The only problem, GD doesn't seem to handle TIF natively, so you may have to do a conversion to an uncompressed JPEG or PNG.

    From the GD Docs:

    $index = $image->getPixel(x,y) object method This returns the color table index underneath the specified point. + It can be combined with rgb() to obtain the rgb color underneath the + pixel. Example: $index = $myImage->getPixel(20,100); ($r,$g,$b) = $myImage->rgb($index);


    grep
    One dead unjugged rabbit fish later

      Or, perhaps they could use Imager. It has a getpixel method:

      my $color = $img->getpixel(x=>50, y=>70);

      ...and can read TIFF files (given the existence of libtiff).

      --
      "Go up to the next female stranger you see and tell her that her "body is a wonderland."
      My hypothesis is that she’ll be too busy laughing at you to even bother slapping you.
      " (src)

      Actually you were right, Image::Magick does have a method to query pixel color:

      $image->Get('Pixel[x,y]')

      It returns a scalar value containing a comma seperated list R,G,B,A. There's also $image->GetPixels(), but I've had some issues getting accurate color readings from it, though that's likely an error on my part.

      Just Another Perl Alchemist
Re: Perl Image Analysis
by explorer (Chaplain) on Oct 04, 2006 at 21:39 UTC
      Sounds impressive. However, it also sounds rather complicated. Is there some sample PDL code somewhere? I looked through the site you refer to and did not find any example code - just lots of documentation, but almost no sample code of "we did X by writing this code".

        Yes, the problem with PDL is the docs. Exists a PDL Book, but it have 5 years old.

        For my project, I finished it with the help of excellent people of PDL mailing list.

        It is a pity that one of the tools more powerful than exists in Perl, has so little development and diffusion.

Re: Perl Image Analysis
by lparsons42 (Novice) on Oct 04, 2006 at 21:14 UTC
    Ok, that is a good start. I set up the Imager module, and was able to get scalar values for a pixel. Now I just need to work on figuring out what to do with them.
    Is there a way that any of these methods could give me just a greyscale intensity, rather than RGB values? I don't have any color data on these images, so the RGB values are kinda obfuscating the interpretation.
    Not that I'm entirely opposed to obfuscation, being as I am writing in Perl, after all... :)

    I submitted this thread while waiting for my new member email to come through. I suspect it may have been holed up for a while by our foolish spam filter...
      You can get just the first channel (your grey value) with the getsamples() method:
      # get all the samples for row $y my @samples = $image->getsamples(y => $y, channels => [ 0 ]);
      If your image does have only one channel (check $image->getchannels) the channels argument is unneeded so you have:
      my @samples = $image->getsamples(y => $y);
      You can also get the samples as a string of bytes:
      my $samples = $image->getsamples(y => $y);
      You don't mention the precision of your data, but Imager currently always reads TIFFs at 8-bits/sample, even if the TIFF has higher precision.
        Yes, this is looking more promising. The triplet values were not as useful as hoped for. I tried to use the getsamples() method to sample just one pixel, however, and the results were like:
        «ÑçÇ¡yÀʾ²¾í©k~Áµ¨rw U=9dyµàТI*\ZGpë«
        I'm not sure how to compare those values to each other... My code to do this was as follows:
        ### #it appears there may actually be a way to read the grey channel #using the "getsamples" routine my $ycoord = 5; my $xcoord = 5; my $sample = $img->getsamples(y => $ycoord, x => $xcoord); print "we sampled 5,5 to have a value of $sample\n";
        I tried sampling two different points that I knew to be quite different by this method, which is how I got those two odd strings above. I'll have to look further into the Perldocs for Imager, it appears :)

      I may be wrong, but I would expect any of the modules mentioned to return just an intensity in the case of a true grayscale image, I could be wrong, or it could be a case of the image technically being a color image that just so happens to only contain grays. Nonetheless, if all else fails, just use any one of the values, ignore the others, they should be the same.

      Well, just did some testing, and at least in regards to Image::Magick it still returns RGBA values, I can't speak for the others haven't had much experience with them, so at least in the case of Image::Magick, I would suggest just dumping the spare values.

      Just Another Perl Alchemist
      <#!/usr/bin/perl use warnings; use strict; use Imager; my $file = shift; my $img = Imager->new(); $img->open(file=>$file) or die $img->errstr(); my $newimg = $img->convert(preset=>'grey'); $newimg->write(file=>'gray.jpg');
      What I have found with Imager, is that is has some very powerful, but basic tools. If you look at them closely, you probably can figure out a sequence of operations to acheive what you want. Look at "perldoc Imager" to get a list of it's sub modules, check out Imager::Filters and it's $img->difference method.

      I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: Perl Image Analysis
by mattr (Curate) on Oct 05, 2006 at 11:44 UTC
    FWIW I had a good experience with Perl-Fu, which is a server run from within the gimp to respond to commands from Perl. (also you can do batch stuff with the Gimp I believe). There are also a bunch of gimp shells I think python-fu and emacs have them, I used pgshell in perl. It let me paste a series of commands on the command line and see them executed so I could confirm my perl program's image manipulation routines would drive gimp correctly. As for grayscale I don't remember, but of course you can convert the image to grayscale, use a single channel as grayscale, or just average the r,g,b yourself. That said I don't quite understand why you are splitting the image into files. Anyway above poster re PDL seems on target but if you really just want pixel values the image magick or gimp will do it for you.
Re: Perl Image Analysis
by jfroebe (Parson) on Oct 05, 2006 at 02:40 UTC

    Maybe I'm just paranoid but this kind of sounds like a method that could possibly be used to defeat the "type the characters you see in the box on the right so we know you are human and not a bot". Please tell me I'm wrong here...

    Jason L. Froebe

    Team Sybase member

    No one has seen what you have seen, and until that happens, we're all going to think that you're nuts. - Jack O'Neil, Stargate SG-1

      I honestly hadn't even considered that. I have a very different type of array that I am working with - similar to the affymetrix DNA microarrays (except its with proteins and its colorless).
      I'm not sure how well one could use this technique to find words in a pattern like that. Maybe if you knew what dictionary was used to generate the word (so you could check for feasibility) it might be useful for that. But being as the ones I've seen use upper and lowercase letters, and varied fonts at varied heights, I think that guessing letters could be fairly difficult.

      From the OP:

        I am working with (physical) array data, that is scanned in at 100 microns / pixel.

      You're wrong. :) Sounds like an electron microscope image to me, but then, I'm an engineer and not a scientist.

      Alex / talexb / Toronto

      "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

        Actually, it is a scanner. Its a "Typhoon 9410" that can go to 10 microns per pixel in certain modes.
        The EM that we have here does much, much better than that. I suppose if I could coat a fly with fluorescent goo I could image it on this in the way that one could with an EM of this resolution :)
      Not really, There is *alot* of work involved with breaking captchas, simply finding grayscale is not going to help you at all.
      That thought crossed my mind but the large image size hinted at and the use of the TIFF image format quickly steered me towards bioinformatics.
Re: Perl Image Analysis
by Anonymous Monk on Oct 09, 2006 at 16:05 UTC

    Card-carrying bioinformaticist here....

    Are you positive you can't segment using GenePix or an equivalent? Their spot-segmentation algorithms are really very nicely done, and modern versions handle one, two, and four-colour arrays. You don't have to scan on an Axon scanning to use GenePix -- it should handle your Typhoon data no problem. The reason I suggest this is that segmentation is pretty tricky, and when you suggest "corresponding pixels in two spots" type comparisons, that means that even a one-pixel segmentation error will corrupt the comparison. If I reviewering a paper doing this I'd be extremely concerned, and would probably ask for: a direct comparison to an established quanting program on a spot-by-spot basis, direct comparison to an established quanting program on an overall results basis, and public release of the code used for your program. Just my two cents....

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://576382]
Approved by neniro
Front-paged by diotalevi
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-03-19 06:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found