Subscribe Bookmark RSS Feed

Open Image (jpg) Files, Perform Analysis and move onto next Image

d_barnett

Community Trekker

Joined:

Nov 30, 2011

I am very interested in using JMP to do automatic image processing and analysis and I have a script ( heavily based on John Pontes add-in - and information gathered from his excellent blog John Ponte, Author at JMP Blog)  that I can run on one image at a time on images but what I really want to do next is to create  a 'looping' script that does the following

  1. counts the number of .jpg files in a directory.
  2. one-by-one opens an image, puts the information available ( I'm using John Pontes Image analyser add-in and script for this) into a data table
  3. does a basic analysis ( mean of columns & rows etc.)
  4. saves this with the jpg filename
  5. closes the files down and moves onto the next image.


I have a number of small problems with this but the main ones are that when I use the following

For( i = 1, i <= N Items( files ), i++,

  If( Ends With( files[i], ".jpg" ),

  Open( files[i] );

);

the open ( files); opens the jpg files in another program ( the default prog that I don't want to change). How do I get it so that it opens up in JMP using the following ( or something else if it's better)

img = New Image( "thefilenameofthe.jpg" );

w = New Window( "image", img );

I can then perform the analysis and close this all down and loop back around until all of the images have been analysed.

Regards



David

5 REPLIES
ian_jmp

Staff

Joined:

Jun 23, 2011

This should put the image files in a folder into a JMP table:

// ian.cox@jmp.com:23Jun2014

Names Default To Here(1);

dir = Pick Directory("Pick a directory containing image files:");

fList = FilesInDirectory(dir);

if (NItems(fList) < 1, Print("No files found in folder "||dir||"."); Beep(); Throw());

dt = NewTable("Images from "||dir,

NewColumn("File Path", Character, Nominal),

NewColumn("Image", Expression), AddRows(NItems(fList))

);

for (f=1, f<=Nitems(fList), f++,

fp = dir||"/"||fList[f];

Column(dt, "File Path")[f] = fp;

Try(Column(dt, "Image")[f] = NewImage(fp)); // Use 'Try()' in case it's not an image file

);

Craige_Hales

Staff

Joined:

Mar 21, 2013

add the file type parameter.  then the returned value will be a picture object.  It will probably work even if you mix and match PNG, JPG, GIF; it tells JMP to return the picture rather than falling back on the OS default program for the extension.


open("$desktop/setFont.PNG","PNG")

New Image(

  Char To Blob(

  "640745eJxkugdUU0v3PgyCIFKiotKDCsL10ovUEFBQRJodKQJKLyF0gpSIKIjSpEgnCgoqVVrooRk6obcACUaaG...


or use newimage to get the picture object.


newimage("$desktop/setFont.PNG")

New Image(

  Char To Blob(

  "640745eJxkugdUU0v3PgyCIFKiotKDCsL10ovUEFBQRJodKQJKLyF0gpSIKIjSpEgnCgoqVVrooRk6obcACUaaG...

newimage is simpler; open might be needed if the image is a URL or Blob.

Craige
d_barnett

Community Trekker

Joined:

Nov 30, 2011

Many apologies, I wasn't clear enough in my original post. What I want to do is to put the pixel information into a data table, not the original image itself.

this is, in effect, automating the ImageToDatatable JSL script that has already been written but go through each image within a folder and save the resulting data table with any resultant analysis of the pixels in the same folder.

the x & y co-ordinates along with the RGB, I and HSL are sufficient for me to carry out any analysis I require. I have attached an example data table that I can perform analysis on, I have also attached the original image where this data was taken from, I have a few thousand of these which I need to go through so doing them one at a time would be nearly impossible.

apologies again for the bad wording and lack of clarity in the original post.

David.

Craige_Hales

Staff

Joined:

Mar 21, 2013

path = "$desktop/temp/";

files = Files In Directory( path );

For( ifile = 1, ifile <= N Items( files ), ifile++,

  filename = files[ifile];

  If( Right( filename, 4 ) == ".jpg",

  pic = Open( path || filename, "jpg" );

  jslcolor = pic << getpixels();

  {red, green, blue} = Color To RGB( jslcolor );

  {hue, lightness, saturation} = Color To HLS( jslcolor );

  nr = N Rows( jslcolor );

  nc = N Cols( jslcolor );

  dt = New Table( Substr( filename, 1, Length( filename ) - 4 ),

  addrows( nr * nc ),

  New Column( "x" ),

  New Column( "y" ),

  New Column( "red", setvalues( red ) ),

  New Column( "green", setvalues( green ) ),

  New Column( "blue", setvalues( blue ) ),

  New Column( "hue", setvalues( hue ) ),

  New Column( "lightness", setvalues( lightness ) ),

  New Column( "saturation", setvalues( saturation ) ),

  );

  irow = 0;

  For( iy = 1, iy <= nr, iy++,

  For( ix = 1, ix <= nc, ix++,

  irow++;

  dt:y[irow] = iy;

  dt:x[irow] = ix;

  )

  );

  // do something with dt

  Wait( 1 );

  Close( dt, "nosave" );

  );

);

Craige
JohnPonte

Staff

Joined:

Jun 17, 2013

I just came across this post and thought I'd add a couple of points, in case it is still helpful.

One thing I'll suggest is that you can use NewImage(), instead of Open() for the image file. Open() is a more general function that has to figure out what you are opening. In that process, it uses OS functionality, like opening your image in another program. img = NewImage("filename.jpg"); will open the image file and create a JSL image, returning you the handle to it.

The other suggestion is that you can use another script I did (before the Image Analyzer) on the File Exchange, called ImageToDatatable. It will convert your image into a data table, similarly to the Image Analyzer, but you won't get all the rest of what the Image Analyzer does.

Wrap that in the loop as Craige@JMP shows (above) and you should be good to go.