documents:120206pyip_cooking:python_imagej_cookbook
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
documents:120206pyip_cooking:python_imagej_cookbook [2022/03/02 07:16] – [JAVADOCS] kota | documents:120206pyip_cooking:python_imagej_cookbook [2024/10/08 17:45] (current) – [Accessing multiple files to load image sequences] kota | ||
---|---|---|---|
Line 410: | Line 410: | ||
</ | </ | ||
==== Accessing multiple files to load image sequences ==== | ==== Accessing multiple files to load image sequences ==== | ||
+ | |||
+ | A simple way is to use glob package (file not loaded in this example). | ||
+ | <code python linenums: | ||
+ | import glob, os | ||
+ | from ij.io import DirectoryChooser | ||
+ | |||
+ | srcDir = DirectoryChooser(" | ||
+ | for filename in glob.glob(os.path.join(srcDir, | ||
+ | print(os.path.basename(filename)) | ||
+ | </ | ||
Here is a cool script written by Christian Tischer for loading image series using file prefix as dictionary keys. | Here is a cool script written by Christian Tischer for loading image series using file prefix as dictionary keys. | ||
Line 787: | Line 797: | ||
zip command creates a list of tuples from elements of arrays a and b. | zip command creates a list of tuples from elements of arrays a and b. | ||
+ | ==== Using Java8 Stream ==== | ||
+ | |||
+ | Stream-related syntax introduced from Java8 is useful for writing clear codes, but cannot be directly used in Jython. Below is a way to use StreamAPI, by introducing Jython classes implementing the Consumer interface. I took this idea from [[https:// | ||
+ | |||
+ | <code python> | ||
+ | from java.util.Arrays import asList | ||
+ | from java.util.function import Predicate, Consumer, Function | ||
+ | from java.util.stream import Collectors | ||
+ | from java.util import Arrays | ||
+ | |||
+ | |||
+ | class jc(Consumer): | ||
+ | def __init__(self, | ||
+ | self.accept=fn | ||
+ | |||
+ | class jf(Function): | ||
+ | def __init__(self, | ||
+ | self.apply = fn | ||
+ | |||
+ | class jp(Predicate): | ||
+ | def __init__(self, | ||
+ | self.test = fn | ||
+ | | ||
+ | def jprint(x): | ||
+ | print x | ||
+ | |||
+ | tt = [" | ||
+ | c = Arrays.stream(tt).count() | ||
+ | print c | ||
+ | |||
+ | print " | ||
+ | Arrays.stream(tt).forEach(jc(lambda x: jprint(" | ||
+ | |||
+ | print " | ||
+ | Arrays.stream(tt).parallel().forEach(jc(lambda x: jprint(" | ||
+ | |||
+ | print "has b?", Arrays.stream(tt).anyMatch(jp(lambda x: x==" | ||
+ | print "has z?", Arrays.stream(tt).anyMatch(jp(lambda x: x==" | ||
+ | |||
+ | # convert to Java List<> | ||
+ | jtt = Arrays.asList(tt) | ||
+ | |||
+ | jtt.stream().forEach(jc(lambda x: jprint(" | ||
+ | </ | ||
===== Event Listener ===== | ===== Event Listener ===== | ||
Line 839: | Line 893: | ||
</ | </ | ||
+ | ===== GUI: wait for user ===== | ||
+ | |||
+ | To pause the script processing and wait for the user input (e.g. creating amanual ROI), use WaitForUserDialog class. | ||
+ | |||
+ | <code python> | ||
+ | from ij.gui import WaitForUserDialog | ||
+ | |||
+ | print(" | ||
+ | wud = WaitForUserDialog(" | ||
+ | print(" | ||
+ | wud.show() | ||
+ | print(" | ||
+ | </ | ||
===== HashMap ===== | ===== HashMap ===== | ||
Line 1023: | Line 1090: | ||
maskimp.show() | maskimp.show() | ||
</ | </ | ||
+ | |||
+ | === Stack to Mask by a threshold value === | ||
+ | |||
+ | Here is an example script to create a mask from an 8-bit stack using intensity thresholding. | ||
+ | The threshold value is derived by the Otsu algorithm using the full stack histogram. | ||
+ | |||
+ | < | ||
+ | from ij import IJ, ImagePlus, ImageStack | ||
+ | from ij.plugin import ChannelSplitter | ||
+ | from ij.process import StackStatistics | ||
+ | from fiji.threshold import Auto_Threshold | ||
+ | |||
+ | #imp = IJ.openImage(" | ||
+ | imp = IJ.getImage() | ||
+ | imps = ChannelSplitter.split( imp ) | ||
+ | imp1 = imps[0] | ||
+ | imp1bin = imp1.duplicate() | ||
+ | |||
+ | # get auto threshold value | ||
+ | stats = StackStatistics(imp1bin) | ||
+ | histdouble = stats.histogram() | ||
+ | |||
+ | # need this conversion from double to int | ||
+ | histint = map(lambda x:int(x), histdouble) | ||
+ | th = Auto_Threshold.Otsu(histint) | ||
+ | |||
+ | for i in range(imp1bin.getStackSize()): | ||
+ | ip = imp1bin.getStack().getProcessor( i + 1) | ||
+ | ip.threshold(th) | ||
+ | |||
+ | IJ.run(imp1bin, | ||
+ | imp1bin.show() | ||
+ | </ | ||
+ | |||
+ | To do this by accessing the pixel array of the stack, here is the way. It takes a longer time than above, so this is just to show the technique to process by pixel values using float processor pixel array object. | ||
+ | |||
+ | <code python> | ||
+ | |||
+ | from ij import IJ, ImagePlus, ImageStack | ||
+ | from ij.plugin import ChannelSplitter | ||
+ | from ij.process import StackStatistics | ||
+ | from ij.process import FloatProcessor | ||
+ | from fiji.threshold import Auto_Threshold | ||
+ | import jarray | ||
+ | |||
+ | imp = IJ.openImage(" | ||
+ | #imp = IJ.getImage() | ||
+ | imps = ChannelSplitter.split( imp ) | ||
+ | imp1 = imps[0] | ||
+ | ww = imp1.getWidth() | ||
+ | hh = imp1.getHeight() | ||
+ | binstack = ImageStack( ww, hh) | ||
+ | |||
+ | # get auto threshold value | ||
+ | stats = StackStatistics(imp1) | ||
+ | histdouble = stats.histogram() | ||
+ | histint = map(lambda x:int(x), histdouble) | ||
+ | th = Auto_Threshold.Otsu(histint) | ||
+ | |||
+ | for i in range(imp1.getStackSize()): | ||
+ | slicepixA = imp1.getStack().duplicate().convertToFloat().getPixels(i + 1) | ||
+ | # pixmin = reduce(min, slicepixA) | ||
+ | # pixmax = reduce(max, slicepixA) | ||
+ | # print " | ||
+ | slicepixA = map(lambda x: 0.0 if x<th else 255.0, slicepixA) | ||
+ | fp = FloatProcessor( ww, hh, slicepixA, None) | ||
+ | bp = fp.convertToByteProcessor() | ||
+ | binstack.addSlice(str(i+1), | ||
+ | |||
+ | binimp = ImagePlus(" | ||
+ | binimp.show() | ||
+ | </ | ||
+ | |||
==== ROI manager ==== | ==== ROI manager ==== | ||
Line 1819: | Line 1959: | ||
fullimps[0].show() | fullimps[0].show() | ||
</ | </ | ||
+ | |||
+ | If you do not want to open all images (called sereies) in multi-image CZI files, replace | ||
+ | < | ||
+ | open.setOpenAllSeries(True) | ||
+ | </ | ||
+ | with | ||
+ | < | ||
+ | options.setSeriesOn(seriesIndex, | ||
+ | </ | ||
+ | with " | ||
See here for more on metadata parsing and so on: [[https:// | See here for more on metadata parsing and so on: [[https:// | ||
Line 2241: | Line 2391: | ||
===== Plugin: MorphoLibJ ===== | ===== Plugin: MorphoLibJ ===== | ||
+ | Javadoc: [[http:// | ||
==== Distance Transform Watershed 3D ==== | ==== Distance Transform Watershed 3D ==== | ||
documents/120206pyip_cooking/python_imagej_cookbook.1646205415.txt.gz · Last modified: 2022/03/02 07:16 by kota