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
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.
[*Edit to original post by staff member sseligman. Second part of user question added here to original post.]
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.
Regards
David
Consolidating two replies to this post as the solution.
Part 1 from staffer @Craige_Hales:
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" );
);
);
Part 2 from staffer @JohnPonte:
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_Hales shows (above) and you should be good to go.
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
);
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.
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.
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" );
);
);
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.
Consolidating two replies to this post as the solution.
Part 1 from staffer @Craige_Hales:
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" );
);
);
Part 2 from staffer @JohnPonte:
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_Hales shows (above) and you should be good to go.