SaveAs in a loop with ImageJ - for-loop

I'm brand new to imageJ and its macros, I can't save a Results file from Particle Analyze in a loop.
Here is my code, made of what I just learned on internet and I just can't include [i] in the saveAs function and there is a mismatch with the saving of the images while I have not even try yet to save it...
path1=getDirectory("Mydir");
list=getFileList(path1);
path2=getDirectory("My output dir");
setBatchMode(true);
for(i=0;i<list.length;i++){
open(path1+list[i]);
run("8-bit");
run("Analyze Particles...", "size=0-Infinity circularity=0.00-1.00 show=[Bare Outlines] display clear");
selectWindow("Results");
saveAs("Results", path2+"Results.xls");
close();
}
setBatchMode(false);
run("Close");

To save the Results window in each cycle of your for loop, you can add the counter variable i to the file name string:
saveAs("Results", path2+"Results" + i + ".xls");
It might be a good idea to also include the original image file name into the results file name, such as:
saveAs("Results", path2+"Results" + list[i] + ".xls");
NB: I had to add to add setAutoThreshold("Default"); before the Analyze Particles... command to make your macro work on sample images like the Blobs example image, because the command need a thresholded/binary image.

Related

Writing Macro in ImageJ to open, change color, adjust brightness and resave microscope images

I'm trying to write a code in Image J that will:
Open all images in separate windows that contains "488" within a folder
Use look up tables to convert images to green and RGB color From ImageJ, the commands are: run("Green"); and run("RGB Color");
Adjust the brightness and contrast with defined values for Min and Max (same values for each image).
I know that the code for that is:
//run("Brightness/Contrast..."); setMinAndMax(value min, value max); run("Apply LUT");
Save each image in the same, original folder , in Tiff and with the same name but finishing with "processed".
I have no experience with Java and am very bad with coding. I tried to piece something together using code I found on stackoverflow and on the ImageJ website, but kept getting error codes. Any help is much appreciated!
I don't know if you still need it, but here is an example.
output_dir = "C:/Users/test/"
input_dir = "C:/Users/test/"
list = getFileList(input_dir);
listlength = list.length;
setBatchMode(true);
for (z = 0; z < listlength; z++){
if(endsWith(list[z], 'tif')==true ){
if(list[z].contains("488")){
title = list[z];
end = lengthOf(title)-4;
out_path = output_dir + substring(title,0,end) + "_processed.tif";
open(input_dir + title);
//add all the functions you want
run("Brightness/Contrast...");
setMinAndMax(1, 15);
run("Apply LUT");
saveAs("tif", "" + out_path + "");
close();
};
run("Close All");
}
}
setBatchMode(false);
I think it contains all the things you need. It opens all the images (in specific folder) that ends with tif and contains 488. I didn't completely understand what you want to do with each photo, so I just added your functions. But you probably won't have problems with adding more/different since you can get them with macro recorder.
And the code is written to open tif files. If you have tiff just be cerful that you change that and also change -4 to -5.

Copy slide with images python pptx

My end goal is to change the theme of a presentation. To do this, I have created a source template and new template (with the correct theme). I iterate over each slide in the source template then add a new slide to the new template with the contents of the source using the code below - source. If there is a better way to do this I'd love to hear it.
This works great for text and text boxes, however the test image cannot be displayed in the new powerpoint (show in the image below):
Code
def copy_slide_from_external_prs(self, src, idx, newPrs):
# specify the slide you want to copy the contents from
src_slide = src.slides[idx]
# Define the layout you want to use from your generated pptx
slide_layout = newPrs.slide_layouts[2]
# create now slide, to copy contents to
curr_slide = newPrs.slides.add_slide(slide_layout)
# remove placeholders
for p in [s.element for s in curr_slide.shapes if 'Text Placeholder' in s.name or 'Title' in s.name]:
p.getparent().remove(p)
# now copy contents from external slide, but do not copy slide properties
# e.g. slide layouts, etc., because these would produce errors, as diplicate
# entries might be generated
for shp in src_slide.shapes:
el = shp.element
newel = copy.deepcopy(el)
curr_slide.shapes._spTree.insert_element_before(newel, 'p:extLst')
return newPrs
I was trying many different solutions and tried creating a new Picture using the image.blob property in the source image. However, then the image does not have an element. Do I need to convert the blob to a PNG, save it, then create a new image using that saved PNG?
There must be a better way to do this. Again, I just want to change the theme.
Thanks in advance!
Here is the workaround I developed. I first check if the shape is an image, and if it is, I write the image to a local directory. Then I add a picture to the slide using that saved image. Finally, I delete the locally saved image.
Now this copy_slide function works for images:
def copy_slide_from_external_prs(src, idx, newPrs):
# specify the slide you want to copy the contents from
src_slide = src.slides[idx]
# Define the layout you want to use from your generated pptx
SLD_LAYOUT = 5
slide_layout = prs.slide_layouts[SLD_LAYOUT]
# create now slide, to copy contents to
curr_slide = newPrs.slides.add_slide(slide_layout)
# create images dict
imgDict = {}
# now copy contents from external slide, but do not copy slide properties
# e.g. slide layouts, etc., because these would produce errors, as diplicate
# entries might be generated
for shp in src_slide.shapes:
if 'Picture' in shp.name:
# save image
with open(shp.name+'.jpg', 'wb') as f:
f.write(shp.image.blob)
# add image to dict
imgDict[shp.name+'.jpg'] = [shp.left, shp.top, shp.width, shp.height]
else:
# create copy of elem
el = shp.element
newel = copy.deepcopy(el)
# add elem to shape tree
curr_slide.shapes._spTree.insert_element_before(newel, 'p:extLst')
# add pictures
for k, v in imgDict.items():
curr_slide.shapes.add_picture(k, v[0], v[1], v[2], v[3])
os.remove(k)
Using code from #Michael-Berk I made very elegant method for copying slides (including images). Check this answer: https://stackoverflow.com/a/73954830/20159015

Save multiple images with one function - AS3 ADOBE AIR

I've got an Array with 17 web links of images
var products:Array;
trace(products)
// Ouput :
"http://www.myWebsite.com/zootopia.jpg"
"http://www.myWebsite.com/james.jpg"
"http://www.myWebsite.com/tom.jpg"
..etc
If I do products[10].movieimage; the output will be the 9th link (something like : "http://www.myWebsite.com/lalaland.jpg")
I'm looking for downloading every images without a dialog box.
I manage to do so for 1 image with the specific link, like that :
function saveImage (event:Event):void {
var stream:URLStream = new URLStream();
var image1:File = File.documentsDirectory.resolvePath("test.jpg");
var fileStream:FileStream = new FileStream();
stream.load(new URLRequest("http://www.myWebsite.com/lalaland.jpg"));
stream.addEventListener(Event.COMPLETE, writeComplete);
        
function writeComplete(evt:Event):void  {
                var fileData:ByteArray = new ByteArray();
                stream.readBytes(fileData,0,stream.bytesAvailable);
                fileStream.openAsync(image1, FileMode.UPDATE);
                fileStream.writeBytes(fileData,0,fileData.length);
                fileStream.close();
trace("writeComplete");
trace(image1.url);
        }
}
Question : Is there a way to download all the images with the web links of my products array ? (and if images already exist, replace them. I could use if (image1.exists){ if (image2.exists){ ..etc for each image. But maybe there is a simplier solution)
If you could show me how, with a bit of code, I could that.
Also, note that I'd like to load the images then in Uiloader, like that :
function loadImages():void {
uiloader1.source = image1.url;
uiloader2.source = image2.url;
etc...
}
Don't over think it. You have your array of images. You have your tested routine for saving one image. Now put it together:
Some function initializes things and kicks it off.
Either splice out (or pop out) an item on the array – OR use a index var to access an item in the array
Pass that to your download function.
When the download completes either pop another item off the array OR increment your index. But first you would test if array.length== 0 OR `index > array.length. If either is true (depending on which method you use), then you are done.
If you want to get fancy you can show a progress bar and update it each time your download completes.

Measure multiple ROIs in imageJ

I'm creating a script for automated measuring fluorescence intensity. I have done some progress, the macro opens the image, split in as many channels as I have and perform some trasformation so that it is possible to execute particle analysis at image 1. Then, what I want is to measure all the created ROIs but I am stacked at this point:
here is my code
dir1 = getDirectory("Choose Source Directory ");
list = getFileList(dir1); // get the list of all filenames in the directory
subst = 3; // set the "subst" variable to 3
Dialog.create("BatchSplitStacks"); // create a dialogue to change the stack divisor
Dialog.addNumber("Number of substacks:", subst); // in the dialogue, get the number of substacks, default is "subst" (=3)
Dialog.show(); // show the above created dialogue
chan = Dialog.getNumber(); // the stack divisor is defined
setBatchMode(false); // do not show the images while processing them
for (i=0; i<list.length; i++) { // go through the files of the folder
showProgress(i+1, list.length); // the progress of the processing of the actual stack is shown in the ImageJ window
open(dir1+list[i]); // open an original stack
name = list[i]; // get the filename of the original stack
run("Stack Splitter", "number="+chan); // run the Stack Splitter plugin with the defined divisor
for (e=0; e<chan; e++) { // for each substack a saving routine is run
dotIndex = lastIndexOf(name, "."); // this line and the following line I took from another macro but I do not know
// substacks with a number below 10 are saved with a suffix and a 2 digit extension (e.g. 01 instead of the standard 1)
saveAs("tiff", dir1+"c0"+e+".tif");
close();
// closing substack
} // next saving routine
close(); // closing current original stack
open(dir1+"c02.tif");
run("Enhance Contrast", "saturated=0.35");
run("Enhance Contrast", "saturated=0.35");
run("Enhance Contrast", "saturated=0.35");
setAutoThreshold("Default");
setAutoThreshold("Default dark");
run("Make Binary");
run("Make Binary");
run("Watershed");
run("Analyze Particles...", "size=0.30-50.00 circularity=0.00-0.70 show=Masks display summarize add in_situ");
open(dir1+"c01.tif");
run("Subtract Background...", "rolling=50");
saveAs("Results", dir1+name+"c02"+ ".txt");
} // move on to next original stack in the folder
Thanks
You can measure all ROIs in the ROI Manager using the Measure button. In a macro, the lines are:
roiManager("Deselect");
roiManager("Measure");
You can learn more macro commands easily by using the Macro Recorder.
You can browse all the available macro functions online.
For more sophisticated per-ROI analysis, you can loop over the ROIs in the manager using the roiManager("count") and roiManager("select", i) commands. The Scale_All_ROIs macro gives an example of this; you can easily load that macro into the Script Editor by opening a new script (File > New > Script) and then choosing it from the Templates > IJ1 Macro menu of the Script Editor.

Making a gif from images

I have a load of data in 100 .sdf files (labelled 0000.sdf to 0099.sdf), each of which contain a still image, and I'm trying to produce a .gif from these images.
The code I use to plot the figure are (in the same directory as the sdf files):
q = GetDataSDF('0000.sdf');
imagesc(q.data');
I've attempted to write a for loop that would plot the figure and then save it with the same filename as the sdf file but to no avail, using:
for a = 1:100
q=GetDataSDF('0000.sdf');
fh = imagesc(q.dist_fn.x_px.Left.data');
frm = getframe( fh );
% save as png image
saveas(fh, 'current_frame_%02d.jpg');
end
EDIT: I received the following errors when trying to run this code:
Error using hg.image/get
The name 'Units' is not an accessible property for an instance of class 'image'.
Error in getframe>Local_getRectanglesOfInterest (line 138)
if ~strcmpi(get(h, 'Units'), 'Pixels')
Error in getframe (line 56)
[offsetRect, absoluteRect, figPos, figOuterPos] = ...
Error in loop_code (line 4)
frm = getframe( fh );
How do I save these files using a for loop, and how do I then use those files to produce a movie?
The reason for the error is that you pass an image handle to getframe, but this function excpects a figure handle.
Another problem is that you always load the same file, and that you saveas will not work for gifs. (For saving figures as static images, maybe print is the better option?)
I tried to modify my own gif-writing loop so that it works with your data. I'll try to be extra explicit in the comments, since you seem to be starting out. Remember, you can always use help name_of_command to display a short Matlab help.
% Define a variable that holds the frames per second your "movie" should have
gif_fps = 24;
% Define string variable that holds the filename of your movie
video_filename = 'video.gif';
% Create figure 1, store the handle in a variable, you'll need it later
fh = figure(1);
for a = 0:99
% Prepare file name so that you loop over the data
q = GetDataSDF(['00' num2str(a,'%02d') 'sdf']);
% Plot image
imagesc(q.dist_fn.x_px.Left.data');
% Force Matlab to actually do the plot (it sometimes gets lazy in loops)
drawnow;
% Take a "screenshot" of the figure fh
frame = getframe(fh);
% Turn screenshot into image
im = frame2im(frame);
% Turn image into indexed image (the gif format needs this)
[imind,cm] = rgb2ind(im,256);
% If first loop iteration: Create the file, else append to it
if a == 0;
imwrite(imind,cm,video_filename,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,video_filename,'gif','WriteMode','append','DelayTime',1/gif_fps);
end
end
One more note: When the size of the data is the same for each plot, it makes sense to only use the plot(or in this case, imagesc) command once, and in later loop iterations replace it with a set(ah,'Ydata',new_y_data) (or in this case set(ah,'CData',q.dist_fn.x_px.Left.data'), where ah is a handle of the plot axes (not the plot figure!). This is orders of magnitude faster than creating a whole new plot in each loop iteration. The downside is that the scaling (here, the color-scaling) will be the same for each plot. But in every case that I have worked on so far, that was actually desirable.

Resources