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

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.

Related

find template image in directory of images

I have a directory of images and an image that I know is in this image directory there is a similar image in the directory saved in a different format and scaled differently, but I dont know where (about 100 000 images).
I want to look for the image and find out its filename inside this directory.
I am looking for a mostly already made soulution which I couldn't find. I found OpenCV but I would need to write code around that. Is there a project like that out there?
If there isn't could you help me make a simple C# console app using OpenCV, I tried their templates but never managed to get SURF or CudaSURF working.
Thanks
Edited as per #Mark Setchell's comment
If the image is identical, the fastest way is to get the file size of the image you are looking for and compare it with the file sizes of the images amongst which you are searching.
I suggest this first because, as Christoph clarifies in the comments, it doesn't require reading the file at all - it is just metadata.
If that yields more than one matching answer, calculate a hash (MD5 or other) and pick the filename that produces the same hash.
Again, as mentioned by Christoph in the comments, this doesn't require decoding the image, or holding the decompressed image in RAM, just checksumming it.
So in the end I used this site and modified the python code used there for searching a directory instead of a single image. There is not much code so the full thing is below:
import argparse
from ast import For, arg
import cv2
from os import listdir
from os.path import isfile, join
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", type=str, required=True,
help="path to input image where we'll apply template matching")
ap.add_argument("-t", "--template", type=str, required=True,
help="path to template image")
args = vars(ap.parse_args())
# load the input image and template image from disk
print("[INFO] loading template...")
template = cv2.imread(args["template"])
cv2.namedWindow("Output")
cv2.startWindowThread()
# Display an image
cv2.imshow("Output", template)
cv2.waitKey(0)
# convert both the image and template to grayscale
templateGray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
imageFileNames = [f for f in listdir(args["image"]) if isfile(join(args["image"], f))]
for imageFileName in imageFileNames:
try:
imagePath = args["image"] + imageFileName
print("[INFO] Loading " + imagePath + " from disk...")
image = cv2.imread(imagePath)
print("[INFO] Converting " + imageFileName + " to grayscale...")
imageGray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
print("[INFO] Performing template matching for " + imageFileName + "...")
result = cv2.matchTemplate(imageGray, templateGray,
cv2.TM_CCOEFF_NORMED)
(minVal, maxVal, minLoc, maxLoc) = cv2.minMaxLoc(result)
(startX, startY) = maxLoc
endX = startX + template.shape[1]
endY = startY + template.shape[0]
if maxVal > 0.75:
print("maxVal = " + str(maxVal))
# draw the bounding box on the image
cv2.rectangle(image, (startX, startY), (endX, endY), (255, 0, 0), 3)
# show the output image
cv2.imshow("Output", image)
cv2.waitKey(0)
cv2.imshow("Output", template)
except KeyboardInterrupt:
break
except:
print(imageFileName)
print("Error")
cv2.destroyAllWindows()
The code above shows any image with match value (what I guess is how much similarity there is between source and template) greater than 0.75
Probably still too low but if you want to use it tweak it to your liking.
Note that this WILL NOT work if the image is rotated and if, like me, you have a bright light source in the template other lightsources will come up as false positives
As for time it took me about 7 hours, where the script paused about every 20 minutes for a false positive until I found my image. I got through about 2/3 of all images.
as a sidenote it took 10 minutes to just build the array of files inside the directory, and it took about 500mb of ram once done
This is not the best answer so if anyone more qualified finds this feel free to write another answer.

SaveAs in a loop with ImageJ

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.

pdfbox - rotation issue

As part of a project I am realizing, there are given pdfdocuments which include forms as JPEG Images within A4 pages inside this documents. If have to extract those JPGs out of the PDF. Later on those JPGs are used to build PDF Documents again.
When I simply open up those Documents with any PDFViewer they seem to have no rotation at all, at least it is not visible. So like this icon the have vertical format.
but when I use this sample code to extract the images :
PDDocument doc = PDDocument.load("/path/to/file);
List pages = doc.getDocumentCatalog().getAllPages();
Iterator iter = pages.iterator();
int i = 0;
while (iter.hasNext()) {
PDPage page = (PDPage) iter.next();
System.out.println(page.getRotation());
System.out.println("ROTATION = " + page.getRotation());;
PDResources resources = page.getResources();
Map pageImages = resources.getXObjects();
if (pageImages != null) {
Iterator imageIter = pageImages.keySet().iterator();
while (imageIter.hasNext()) {
String key = (String) imageIter.next();
if(((PDXObjectImage) pageImages.get(key)) instanceof PDXObjectImage){
PDXObjectImage image = (PDXObjectImage) pageImages.get(key);
image.write2file("/path/to/file" + i);
}
i ++;
}
}
}
all extracted JPGs are horizontal format. Further the sysout on the page.rotation tells me that the rotation is set to 270°.
How is that possible? 270 is set, but the PDF is shown vertical (I am no expert on PDF). I even did page.setRotate(0) before extracting the JPGs, but the images still remain horizontally. I read the following Thread telling how to rotate images before drawing them on the pdf. But i need to rotate them before writing them on the filesystem. What is the best way to achieve that?
Unfortunately, I can not attach any of the documents since they are confidential.

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.

Image Misalignment in Visual Studio application

I have a Visual Studio application with a splash screen image cut into "slices". The positions are specified in the Form Designer so they line up properly on the screen. However, the images are out of place when the application is run on the Chinese version of Windows XP. It looks as if the image slices were "exploded" apart.
What's going on here? Do international versions of Windows have a different meaning of the "top left" coordinate of the picture? How can I force the images to be precisely displayed where I want them?
We found a solution! Apparently the picture boxes stretched out on the Chinese XP PC, but the images they contained did not. The fix was to add code like the following:
Me.PictureBoxIcon.Width = Me.PictureBoxIcon.Image.Width
Me.PictureBoxIcon.Height = Me.PictureBoxIcon.Image.Height
Dim loc As New Point
loc.X = Me.PictureBoxIcon.Location.X
loc.Y = Me.PictureBoxIcon.Location.Y + Me.PictureBoxIcon.Height
Me.PictureBoxAbout.Location = loc
Me.PictureBoxAbout.Width = Me.PictureBoxAbout.Image.Width
Me.PictureBoxAbout.Height = Me.PictureBoxAbout.Image.Height
Hope this helps someone else!
In the OnLoad event of the form, you could always explicitly set the location of each section. If starting at the top left with the first and assuming an array with the images in order:
images[0].Location = new Point(0,0);
for (int i = 1; i < images.Length; i++)
{
images[i].Location = new Point(images[i - 1].Location.X + images[i - 1].Width, 0);
}
That will set the first image to the top left corner and all subsequent images to just after the last image.

Resources