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 [2016/12/08 12:11] – [export ROIs in RoiManager to a SVG file] new. kota | documents:120206pyip_cooking:python_imagej_cookbook [2022/10/16 07:12] (current) – [Using Java8 Stream] kota | ||
---|---|---|---|
Line 3: | Line 3: | ||
This page was last edited at: ~~LASTMOD~~ | This page was last edited at: ~~LASTMOD~~ | ||
+ | For learning image processing using Fiji and Jython scripting, go to excellent tutorials written by Albert Cardona, such as [[https:// | ||
+ | |||
+ | This page is like a cookbook: there are no details about how to do programming, | ||
+ | |||
+ | Other resources: | ||
+ | |||
+ | [[https:// | ||
===== Jython Interpreter ===== | ===== Jython Interpreter ===== | ||
A way to run jython script from jython interpreter, | A way to run jython script from jython interpreter, | ||
Line 84: | Line 91: | ||
for j in range(imp.getHeight()): | for j in range(imp.getHeight()): | ||
+ | </ | ||
+ | |||
+ | ===== ImageJ2 / SciJava ===== | ||
+ | |||
+ | ==== Running a script from another script ==== | ||
+ | |||
+ | <code python> | ||
+ | #@ ScriptService scriptService | ||
+ | |||
+ | fullscript = "#@ String A_STRING\n" | ||
+ | "#@ Boolean (label=' | ||
+ | |||
+ | scriptmodule = scriptService.run(" | ||
+ | scriptInputmaps = scriptmodule.getInputs() | ||
+ | |||
+ | print scriptmodule.getOutputs() | ||
+ | print scriptInputmaps | ||
+ | # how can we know the dialog was Canceled? | ||
+ | print scriptmodule.isInputResolved(' | ||
</ | </ | ||
Line 95: | Line 121: | ||
print op.getDirectory()+ op.getFileName() | print op.getDirectory()+ op.getFileName() | ||
</ | </ | ||
+ | |||
+ | ==== Getting the directory where the curently opened image is stored ==== | ||
+ | <code python: | ||
+ | from ij import IJ | ||
+ | |||
+ | imp = IJ.getImage() | ||
+ | print imp.getOriginalFileInfo().directory | ||
+ | </ | ||
+ | |||
+ | ... can also be done by '' | ||
+ | |||
+ | Be careful not to mix with the usage of '' | ||
+ | |||
==== Regular Expression to get meta information from file name ==== | ==== Regular Expression to get meta information from file name ==== | ||
Line 101: | Line 140: | ||
Here is an example, using re package. To construct pattern, several web services are available such as: | Here is an example, using re package. To construct pattern, several web services are available such as: | ||
- | http:// | + | http:// |
+ | or\\ | ||
+ | https:// | ||
<code python linenums: | <code python linenums: | ||
Line 200: | Line 242: | ||
</ | </ | ||
+ | Fiji comes with ApacheIO library, and can be used quite conveniently for disintegrating file paths. See [[https:// | ||
+ | <code python linenums: | ||
+ | from org.apache.commons.io import FilenameUtils | ||
+ | |||
+ | srcpath = '/ | ||
+ | |||
+ | |||
+ | baseName = FilenameUtils.getBaseName(srcpath) | ||
+ | print " | ||
+ | |||
+ | ext = FilenameUtils.getExtension(srcpath) | ||
+ | print " | ||
+ | |||
+ | filename = FilenameUtils.getName(srcpath) | ||
+ | print "File name: ", filename | ||
+ | |||
+ | pathWOext = FilenameUtils.removeExtension(srcpath) | ||
+ | print " | ||
+ | |||
+ | # outputs | ||
+ | # | ||
+ | # Basename: | ||
+ | # Extension: | ||
+ | # File name: data.csv | ||
+ | # Fullpath without ext: / | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ==== Loading a textfile as String ==== | ||
+ | |||
+ | <code python linenums: | ||
+ | path = "/ | ||
+ | with open(inpath, | ||
+ | data = myfile.read() | ||
+ | print data | ||
+ | </ | ||
+ | |||
+ | ==== Saving String as a textfile ==== | ||
+ | |||
+ | <code python linenums: | ||
+ | with open("/ | ||
+ | text_file.write(" | ||
+ | text_file.close() | ||
+ | </ | ||
==== Loading CSV file ==== | ==== Loading CSV file ==== | ||
Line 428: | Line 515: | ||
This is an expaple of using regular expression to match file names, and to collect images as a ImagePlus array then convert it to a Hyperstack. | This is an expaple of using regular expression to match file names, and to collect images as a ImagePlus array then convert it to a Hyperstack. | ||
- | https:// | + | https:// |
<code python linenums: | <code python linenums: | ||
Line 534: | Line 621: | ||
</ | </ | ||
+ | ==== Creating JSON object ==== | ||
+ | |||
+ | JSON object can be directly created from Java Maps. | ||
+ | Here, we use TreeMap to keep the ordering of Map elements. | ||
+ | |||
+ | <code python> | ||
+ | from java.util import TreeMap | ||
+ | from org.json import JSONObject | ||
+ | |||
+ | amap = TreeMap() | ||
+ | amap.put(" | ||
+ | amap.put(" | ||
+ | amap.put(" | ||
+ | jo = JSONObject(amap) | ||
+ | print str(jo) | ||
+ | </ | ||
+ | |||
+ | This code yields: | ||
+ | < | ||
+ | {" | ||
+ | </ | ||
+ | |||
+ | ==== Generating Time Stamp String ==== | ||
+ | |||
+ | <code python> | ||
+ | from java.util import Date | ||
+ | from java.text import SimpleDateFormat | ||
+ | |||
+ | timeStamp = SimpleDateFormat(" | ||
+ | print timeStamp | ||
+ | </ | ||
===== Arrays (Lists) ===== | ===== Arrays (Lists) ===== | ||
Line 540: | Line 658: | ||
We first start with Python list (or for me is " | We first start with Python list (or for me is " | ||
- | ==== Concatenate | + | ==== Appending Elements to a List ==== |
+ | |||
+ | Two ways to append an element to a list. | ||
+ | < | ||
+ | a = [] | ||
+ | a.append(1) | ||
+ | a.append(2) | ||
+ | print a | ||
+ | # [1, 2] | ||
+ | |||
+ | b = [] | ||
+ | b = b + [1] | ||
+ | b = b + [2] | ||
+ | print b | ||
+ | # [1, 2] | ||
+ | #... can be also written like | ||
+ | b = [] | ||
+ | b += [1] | ||
+ | b += [2] | ||
+ | print b | ||
+ | # [1, 2] | ||
+ | |||
+ | </ | ||
+ | ==== Concatenate | ||
<code python linenums: | <code python linenums: | ||
a = [1, 2, 3] | a = [1, 2, 3] | ||
Line 591: | Line 732: | ||
imgarray = jarray.array([imp1, | imgarray = jarray.array([imp1, | ||
colorimp = RGBStackMerge().mergeHyperstacks(imgarray, | colorimp = RGBStackMerge().mergeHyperstacks(imgarray, | ||
+ | </ | ||
+ | |||
+ | ==== Converting Java array types ==== | ||
+ | |||
+ | Sometimes we need to convert the type of Java array e.g. double[] to int[]. For this, there is no magic trick and need to run a loop. Below is a code fragment. | ||
+ | |||
+ | < | ||
+ | from ij.process import StackStatistics | ||
+ | import jarray | ||
+ | |||
+ | stackstats = StackStatistics(imp) | ||
+ | histD = stackstats.histogram() | ||
+ | hist = jarray.zeros(len(histD), | ||
+ | for i in range(len(histD)): | ||
+ | hist[i] = int(histD[i]) | ||
</ | </ | ||
Line 631: | Line 787: | ||
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 683: | Line 883: | ||
</ | </ | ||
+ | ===== 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 769: | Line 982: | ||
imps[0].show() # Channel 1 | imps[0].show() # Channel 1 | ||
imps[1].show() # Channel 2 | imps[1].show() # Channel 2 | ||
+ | </ | ||
+ | |||
+ | ==== Channel Merge ==== | ||
+ | |||
+ | [Image > Color > Merge Channels...] | ||
+ | |||
+ | <code python linenums: | ||
+ | from ij import ImagePlus | ||
+ | from ij.plugin import RGBStackMerge, | ||
+ | |||
+ | impc1 = ImagePlus(" | ||
+ | impc2 = ImagePlus(" | ||
+ | |||
+ | mergeimp = RGBStackMerge.mergeChannels([impc2, | ||
+ | |||
+ | # convert the composite image to the RGB image | ||
+ | RGBStackConverter.convertToRGB(mergeimp) | ||
+ | |||
+ | mergeimp.show() | ||
</ | </ | ||
==== Z projection ==== | ==== Z projection ==== | ||
Line 793: | Line 1025: | ||
outimp.show() | outimp.show() | ||
</ | </ | ||
+ | |||
+ | Another example with the map function | ||
+ | |||
+ | <code python> | ||
+ | # splits multichannel-zstack hyperstack and apply zprojection | ||
+ | from ij import IJ | ||
+ | from ij.plugin import ZProjector | ||
+ | from ij.plugin import ChannelSplitter | ||
+ | |||
+ | def sumzp( imp ): | ||
+ | zp = ZProjector(imp) | ||
+ | zp.setMethod(ZProjector.SUM_METHOD) | ||
+ | zp.doProjection() | ||
+ | zpimp = zp.getProjection() | ||
+ | return zpimp | ||
+ | |||
+ | imp = IJ.getImage() | ||
+ | imps = ChannelSplitter.split( imp ) | ||
+ | zpimps = map(sumzp, imps) | ||
+ | zpimps[0].show() | ||
+ | </ | ||
+ | |||
==== Threshold to create a mask (Binary) ==== | ==== Threshold to create a mask (Binary) ==== | ||
Line 826: | Line 1080: | ||
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 874: | Line 1201: | ||
</ | </ | ||
- | ==== Associating | + | === Saving All ROIs as a single zip file === |
+ | |||
+ | <code py> | ||
+ | import os, jarray | ||
+ | from ij.plugins.frame.RoiManager | ||
+ | |||
+ | outdir = "/ | ||
+ | roizipname = " | ||
+ | roizippath = os.path.join(outdir, | ||
+ | rm = RoiManager.getInstance() | ||
+ | if rm.getCount() > 0: | ||
+ | roiindex = jarray.array(range(0, | ||
+ | rm.setSelectedIndexes(roiindex) | ||
+ | rm.runCommand(' | ||
+ | </ | ||
+ | |||
+ | ==== Union of multiple ROIs ==== | ||
For combining multiple ROIs, {{http:// | For combining multiple ROIs, {{http:// | ||
<code python linenums: | <code python linenums: | ||
+ | from ij.gui import ShaprRoi | ||
sr1 = ShapeRoi(roi1) | sr1 = ShapeRoi(roi1) | ||
sr2 = ShapeRoi(roi2) | sr2 = ShapeRoi(roi2) | ||
sr3 = sr1.or(sr2) | sr3 = sr1.or(sr2) | ||
</ | </ | ||
- | sr3 is then a combination of ROIs roi1 and roi2. | + | sr3 is then a combination of ROIs roi1 and roi2. In similar way, there are AND, XOR, NOT and so on, logical operations. |
==== Mask to selection (Binary to Selection) ==== | ==== Mask to selection (Binary to Selection) ==== | ||
Line 900: | Line 1244: | ||
boundroi = ThresholdToSelection.run(segimp) | boundroi = ThresholdToSelection.run(segimp) | ||
rm.addRoi(boundroi) | rm.addRoi(boundroi) | ||
+ | </ | ||
+ | |||
+ | ==== Adding Overlay in 3D Stack (ROI to Overlay) ==== | ||
+ | |||
+ | < | ||
+ | from ij import IJ | ||
+ | from ij.gui import OvalRoi, Overlay | ||
+ | |||
+ | imp = IJ.getImage() | ||
+ | roi = OvalRoi(170, | ||
+ | roi.setPosition(19) | ||
+ | |||
+ | ol = Overlay() | ||
+ | ol.add(roi) | ||
+ | imp.setOverlay(ol) | ||
+ | ol.setStrokeWidth(2) | ||
</ | </ | ||
Line 921: | Line 1281: | ||
imp = IJ.getImage() | imp = IJ.getImage() | ||
rm = RoiManager.getInstance() | rm = RoiManager.getInstance() | ||
- | if rm is not None: | + | if rm is None: |
- | jrois = rm.getRoisAsArray() | + | |
- | else: | + | |
print ' | print ' | ||
- | sys.exit() | + | sys.exit() |
- | from jarray import | + | # convert ROIs in RoiManager to an array of shapeRois |
+ | jrois = rm.getRoisAsArray() | ||
srois = [ShapeRoi(jroi) for jroi in jrois] | srois = [ShapeRoi(jroi) for jroi in jrois] | ||
# http:// | # http:// | ||
- | + | g2 = SVGGraphics2D(imp.getWidth(), imp.getHeight()) | |
- | g2 = SVGGraphics2D(300, 300) | + | |
g2.setPaint(Color.BLACK) | g2.setPaint(Color.BLACK) | ||
px = 0.0 | px = 0.0 | ||
Line 945: | Line 1303: | ||
se = g2.getSVGElement() | se = g2.getSVGElement() | ||
+ | # writing the file | ||
path = "/ | path = "/ | ||
- | |||
SVGUtils.writeToSVG(File(path), | SVGUtils.writeToSVG(File(path), | ||
</ | </ | ||
+ | |||
+ | One problematic aspect of ROIs are that they could be various, such as lines, rectangles, ovals and polygons. In SVG these different types of ROIs should be treated as different shapes (use different tags). jfreeSVG allows to draw various shapes just by passing java.awt.Shape object, so we do not have to deal with different ROI types in ImageJ and can be moderately generic: IJ ROIs can be converted to IJ ShapeRoi object, which can then be directly converted to java.awt.Shape class. | ||
There are other IJ plugins implementing SVG access. I tried [[http:// | There are other IJ plugins implementing SVG access. I tried [[http:// | ||
Line 969: | Line 1329: | ||
- if the count is larger than " | - if the count is larger than " | ||
- | The jython | + | Explanation in human language: this algorithm first determines two values " |
+ | |||
+ | " | ||
+ | |||
+ | " | ||
+ | |||
+ | The Jython | ||
<code python linenums: | <code python linenums: | ||
Line 1069: | Line 1435: | ||
print " | print " | ||
</ | </ | ||
+ | |||
+ | ==== RGB (Color) Image, Enhance Contrast each channel ==== | ||
+ | |||
+ | To separately set min/max displayed pixel values, add the 3rd argument in setMinAndMax methods of ImageProcessor (in fact, this will be ColorProcessor). | ||
+ | |||
+ | <code python linenums: | ||
+ | from ij import IJ | ||
+ | |||
+ | imp = IJ.getImage() | ||
+ | stk = imp.getStack() | ||
+ | for i in range(stk.getSize()): | ||
+ | ip = stk.getProcessor(i + 1) | ||
+ | # red channel = 4 | ||
+ | ip.setMinAndMax(46, | ||
+ | # green channel = 2 | ||
+ | ip.setMinAndMax(29, | ||
+ | # blue channel = 1 | ||
+ | ip.setMinAndMax(29, | ||
+ | imp.updateAndDraw() | ||
+ | </ | ||
+ | |||
==== Translation of 3D image using ImgLib2 ==== | ==== Translation of 3D image using ImgLib2 ==== | ||
Line 1175: | Line 1562: | ||
For more explanation about this processing, see [[http:// | For more explanation about this processing, see [[http:// | ||
+ | |||
+ | ==== Background Subtraction (Rolling Ball) ==== | ||
+ | |||
+ | Menu item [Process > Subtract Background] | ||
+ | |||
+ | <code python> | ||
+ | from ij import IJ | ||
+ | from ij.plugin.filter import BackgroundSubtracter | ||
+ | |||
+ | imp = IJ.getImage() | ||
+ | |||
+ | ip = imp.getProcessor() | ||
+ | radius = 50.0 | ||
+ | createBackground = False | ||
+ | lightBackground = False | ||
+ | useParaboloid = False | ||
+ | doPresmooth = False | ||
+ | correctCorners = False | ||
+ | |||
+ | bs = BackgroundSubtracter() | ||
+ | bs.rollingBallBackground(ip, | ||
+ | imp.updateAndDraw() | ||
+ | </ | ||
+ | |||
+ | If the image is in RGB, then use a different method (rollingBallBrightnessBackground). | ||
+ | |||
+ | For more explanation about this processing, see [[https:// | ||
==== ImageCalculator ==== | ==== ImageCalculator ==== | ||
Line 1299: | Line 1713: | ||
<code python linenums: | <code python linenums: | ||
+ | from ij import IJ, ImagePlus | ||
from ij.plugin.filter import ParticleAnalyzer as PA | from ij.plugin.filter import ParticleAnalyzer as PA | ||
+ | from ij.measure import ResultsTable | ||
+ | |||
imp = IJ.getImage() | imp = IJ.getImage() | ||
Line 1509: | Line 1926: | ||
cm.setPointSize(3) | cm.setPointSize(3) | ||
</ | </ | ||
- | ===== Plugin: LOCI BioFormats, Replacing OME-TIFF XML ===== | + | ===== Plugin: LOCI BioFormats |
+ | |||
+ | ==== Importing CZI file ==== | ||
+ | |||
+ | <code python linenums: | ||
+ | from loci.plugins import BF | ||
+ | from loci.plugins.in import ImporterOptions | ||
+ | |||
+ | filepath = "/ | ||
+ | |||
+ | # Options for Bioformats plugin, includeing the image path | ||
+ | options = ImporterOptions() | ||
+ | options.setOpenAllSeries(True) | ||
+ | options.setShowOMEXML(False) | ||
+ | options.setStitchTiles(False) | ||
+ | options.setId(filepath) | ||
+ | |||
+ | fullimps = BF.openImagePlus(options) | ||
+ | |||
+ | #fullimps now holds multiple images contained within the czi file. | ||
+ | # open the first one. | ||
+ | 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:// | ||
+ | |||
+ | ==== Count the number of image data set in a CZI file ==== | ||
+ | |||
+ | For just knowing the number of images contained in a CZI file, you do not need to load full image (then it's faster). | ||
+ | |||
+ | <code python linenums: | ||
+ | from loci.formats import ImageReader | ||
+ | |||
+ | r = ImageReader() | ||
+ | filepath = '/ | ||
+ | r.setId( filepath ) | ||
+ | print r.getSeriesCount() | ||
+ | </ | ||
+ | |||
+ | ==== Replacing OME-TIFF XML ==== | ||
<code python linenums: | <code python linenums: | ||
Line 1654: | Line 2120: | ||
===== Plugin: Advanced Weka Segmentation ===== | ===== Plugin: Advanced Weka Segmentation ===== | ||
+ | |||
+ | ==== Adding Eamples from ROI ==== | ||
+ | |||
Training and get Probability image using ROI set as examples (labels). | Training and get Probability image using ROI set as examples (labels). | ||
Line 1685: | Line 2154: | ||
classifiedImage = weka.getClassifiedImage() | classifiedImage = weka.getClassifiedImage() | ||
classifiedImage.show() | classifiedImage.show() | ||
+ | </ | ||
+ | |||
+ | ==== Merging ARFF data files ==== | ||
+ | |||
+ | <code python> | ||
+ | import weka.core.Version | ||
+ | from weka.core import Instances | ||
+ | from weka.core.converters import ConverterUtils | ||
+ | |||
+ | print weka.core.Version().toString() | ||
+ | pp = '/ | ||
+ | data1path = pp+ ' | ||
+ | data2path = pp+ ' | ||
+ | |||
+ | data1 = ConverterUtils.DataSource.read(data1path) | ||
+ | data2 = ConverterUtils.DataSource.read(data2path) | ||
+ | print " | ||
+ | print " | ||
+ | |||
+ | for i in range(data2.size()): | ||
+ | data1.add(data2.get(i)) | ||
+ | |||
+ | dataMerged = data1 | ||
+ | print " | ||
+ | |||
+ | # if data1 and data2 have the same size, the line below can be used. | ||
+ | #dataMerged = Instances.mergeInstances(data1, | ||
+ | |||
+ | dataMargedPath = pp + " | ||
+ | |||
+ | ConverterUtils.DataSink.write(dataMargedPath, | ||
+ | </ | ||
+ | |||
+ | ==== Merging ARFF data files in another way, train and apply classifier ==== | ||
+ | |||
+ | <code python> | ||
+ | from trainableSegmentation import WekaSegmentation | ||
+ | from ij import IJ | ||
+ | |||
+ | # == merging | ||
+ | |||
+ | pp = '/ | ||
+ | data1path = pp+ ' | ||
+ | data2path = pp+ ' | ||
+ | |||
+ | ws = WekaSegmentation() | ||
+ | data1 = ws.readDataFromARFF(data1path) | ||
+ | data2 = ws.readDataFromARFF(data2path) | ||
+ | ws.mergeDataInPlace(data1, | ||
+ | dataBalanced = WekaSegmentation.balanceTrainingData(data1) #optional: can balance the classes | ||
+ | ws.setLoadedTrainingData(dataBalanced) | ||
+ | |||
+ | dataOutpath = pp+ ' | ||
+ | ws.writeDataToARFF(dataBalanced, | ||
+ | |||
+ | # == now train and apply a classifier to an image | ||
+ | |||
+ | if ws.trainClassifier(): | ||
+ | imp = IJ.getImage() | ||
+ | classifiedImage = ws.applyClassifier(imp, | ||
+ | classifiedImage.show() | ||
+ | |||
</ | </ | ||
Line 1728: | Line 2259: | ||
* [[http:// | * [[http:// | ||
* [[http:// | * [[http:// | ||
+ | |||
+ | ===== Plugin: Shape Smoothing ===== | ||
+ | |||
+ | Shape smoothing by reducing the number of Fourier descriptors. | ||
+ | The plugin page is [[http:// | ||
+ | The github page is [[https:// | ||
+ | |||
+ | <code python> | ||
+ | from ij import IJ | ||
+ | from de.biomedical_imaging.ij.shapeSmoothing import ShapeSmoothingUtil | ||
+ | |||
+ | # https:// | ||
+ | |||
+ | imp = IJ.getImage() | ||
+ | ss = ShapeSmoothingUtil() | ||
+ | ss.setBlackBackground(True) | ||
+ | # Relative proportion FDs (%) | ||
+ | thresholdValue = 2 | ||
+ | # FD in % or absolute number | ||
+ | thresholdIsPercentual = True | ||
+ | # If True, a table, containing all FDs, will be shown after processing | ||
+ | doOutputDescriptors = False | ||
+ | |||
+ | ss.fourierFilter(imp.getProcessor(), | ||
+ | </ | ||
===== Plugin: Auto Threshold ===== | ===== Plugin: Auto Threshold ===== | ||
Line 1786: | Line 2342: | ||
Clone the project below, compile and install it as a plugin. | Clone the project below, compile and install it as a plugin. | ||
- | https:// | + | https:// |
<code python linenums: | <code python linenums: | ||
Line 1803: | Line 2359: | ||
print p, resmap.get(p) | print p, resmap.get(p) | ||
</ | </ | ||
+ | |||
+ | ===== Plugin: MiToBo h-dome transformation ===== | ||
+ | |||
+ | h-dome is useful for spot detection in a noisy background. [[https:// | ||
+ | |||
+ | < | ||
+ | from de.unihalle.informatik.MiToBo.core.datatypes.images import MTBImage | ||
+ | from de.unihalle.informatik.MiToBo.morphology import HDomeTransform3D | ||
+ | from ij import IJ | ||
+ | |||
+ | imp = IJ.getImage() | ||
+ | mtb = MTBImage.createMTBImage( imp.duplicate() ) | ||
+ | hdome = HDomeTransform3D(mtb, | ||
+ | hdome.runOp() | ||
+ | mtbdone = hdome.getResultImage() | ||
+ | imp2 = mtbdone.getImagePlus() | ||
+ | imp2.show() | ||
+ | |||
+ | </ | ||
+ | |||
+ | ===== Plugin: MorphoLibJ ===== | ||
+ | |||
+ | Javadoc: [[http:// | ||
+ | ==== Distance Transform Watershed 3D ==== | ||
+ | |||
+ | < | ||
+ | from ij import IJ, ImagePlus | ||
+ | from inra.ijpb.binary import BinaryImages | ||
+ | from inra.ijpb.binary import ChamferWeights3D | ||
+ | from inra.ijpb.data.image import Images3D | ||
+ | from inra.ijpb.watershed import ExtendedMinimaWatershed | ||
+ | |||
+ | |||
+ | imp = IJ.getImage() | ||
+ | |||
+ | normalize = True | ||
+ | dynamic = 2 | ||
+ | connectivity = 6 | ||
+ | |||
+ | #weights = ChamferWeights3D.fromLabel( | ||
+ | #weights = ChamferWeights3D.fromLabel( | ||
+ | weights = ChamferWeights3D.BORGEFORS.getShortWeights() | ||
+ | dist = BinaryImages.distanceMap( imp.getImageStack(), | ||
+ | Images3D.invert( dist ) | ||
+ | #public static final ImageStack extendedMinimaWatershed( ImageStack image, ImageStack mask, int dynamic, int connectivity, | ||
+ | # @param dynamic the maximum difference between the minima and the boundary of a basin | ||
+ | result = ExtendedMinimaWatershed.extendedMinimaWatershed(dist, | ||
+ | outimp = ImagePlus( imp.getShortTitle() + " | ||
+ | outimp.show() | ||
+ | </ | ||
+ | |||
+ | ==== Connected Component 3D labeling ==== | ||
+ | |||
+ | < | ||
+ | from ij import IJ, ImagePlus | ||
+ | from inra.ijpb.binary import BinaryImages | ||
+ | |||
+ | imp = IJ.getImage() | ||
+ | |||
+ | connectivity = 6 | ||
+ | outbitDepth = 16 | ||
+ | outimp = BinaryImages.componentsLabeling(imp, | ||
+ | outimp.setTitle(imp.getShortTitle() + " | ||
+ | outimp.show() | ||
+ | </ | ||
+ | |||
+ | ==== Kill Border Objects, 2D Binary image ==== | ||
+ | |||
+ | <code py> | ||
+ | from ij import IJ, ImagePlus | ||
+ | from inra.ijpb.morphology import Reconstruction | ||
+ | |||
+ | imp = IJ.getImage() #binary image | ||
+ | newip = Reconstruction.killBorders(imp.getProcessor()) | ||
+ | newimp = ImagePlus(" | ||
+ | newimp.show() | ||
+ | </ | ||
+ | |||
+ | ===== Plugin 3D ImageJ Suite ===== | ||
+ | |||
+ | 3D Suite plugin allows you to process / segment / measure 3D image data. | ||
+ | In Fiji, all 3D suite related commands are available under: Plugins > 3D > | ||
+ | |||
+ | The plugin webpage is here: [[https:// | ||
+ | |||
+ | The real power of 3D Suite is using it as a library from scripts and plugins. Many useful classes are implemented for processing, segmenting, and most notably measuring 3D objects. | ||
+ | |||
+ | Source codes are located under framagit: | ||
+ | |||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | |||
+ | The Javadoc I created (Core and Plugins are merged): | ||
+ | |||
+ | * [[https:// | ||
+ | |||
+ | ==== Measureing Spherical 3D ROI positions ==== | ||
+ | |||
+ | The code below shows how to measure spherical 3D ROI in an image. We first create 3 3D spheres and then use them for measuring the mean pixel intensity of those 3D ROIs within a synthetic gradient 3D image. | ||
+ | |||
+ | < | ||
+ | from ij import IJ, ImagePlus | ||
+ | from mcib3d.geom import ObjectCreator3D | ||
+ | from mcib3d.image3d import ImageHandler | ||
+ | |||
+ | oc3d = ObjectCreator3D(200, | ||
+ | oc3d.createSphere(50, | ||
+ | oc3d.createSphere(50, | ||
+ | oc3d.createSphere(50, | ||
+ | |||
+ | imp = oc3d.getPlus() | ||
+ | #imp.show() | ||
+ | |||
+ | obj1 = oc3d.getObject3DVoxels(1) | ||
+ | obj2 = oc3d.getObject3DVoxels(2) | ||
+ | obj3 = oc3d.getObject3DVoxels(3) | ||
+ | |||
+ | |||
+ | impnew = IJ.createImage(" | ||
+ | stack = impnew.getStack() | ||
+ | for i in range(stack.getSize()): | ||
+ | ip = stack.getProcessor(i + 1) | ||
+ | ip.setColor( i * 5 ) | ||
+ | ip.fill() | ||
+ | |||
+ | ima = ImageHandler.wrap( impnew ) | ||
+ | |||
+ | print "Obj1: ", obj1.getPixMeanValue(ima) | ||
+ | print "Obj2: ", | ||
+ | print "Obj3: ", | ||
+ | </ | ||
+ | |||
+ | |||
===== R: Multi-Peak fitting using R ===== | ===== R: Multi-Peak fitting using R ===== | ||
Line 1900: | Line 2589: | ||
See explanation in [[http:// | See explanation in [[http:// | ||
+ | |||
+ | ==== Shell Command ==== | ||
+ | |||
+ | To run Shell command in OSX, here is an example. | ||
+ | |||
+ | <code python> | ||
+ | from java.lang import Runtime | ||
+ | from java.util import Scanner | ||
+ | |||
+ | def runShellCommand( cmd ): | ||
+ | proc = Runtime.getRuntime().exec(cmd) | ||
+ | istream = proc.getInputStream() | ||
+ | scan = Scanner(istream).useDelimiter(" | ||
+ | for ss in scan: | ||
+ | print ss | ||
+ | |||
+ | |||
+ | runShellCommand( " | ||
+ | runShellCommand( "ls -la" ) | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Is docker daemon running? ==== | ||
+ | |||
+ | Check if the docker daemon is running (): | ||
+ | |||
+ | <code python linenums: | ||
+ | from java.lang import Runtime | ||
+ | from java.util import Scanner | ||
+ | |||
+ | |||
+ | def checkDockerRunning( cmd ): | ||
+ | proc = Runtime.getRuntime().exec(cmd) | ||
+ | inputst = proc.getInputStream() | ||
+ | s = Scanner(inputst).useDelimiter(" | ||
+ | if not s.hasNext(): | ||
+ | print " | ||
+ | return False | ||
+ | for ss in s: | ||
+ | print ss | ||
+ | if ss.startswith(" | ||
+ | return True | ||
+ | else: | ||
+ | print " | ||
+ | return False | ||
+ | |||
+ | # below is for OSX. WIth win, just " | ||
+ | cmd = "/ | ||
+ | if checkDockerRunning( cmd ): | ||
+ | print " | ||
+ | else: | ||
+ | print " | ||
+ | </ | ||
+ | |||
+ | ===== JAVADOCS ===== | ||
+ | |||
+ | * 3D ImageJ Suite | ||
+ | * [[http:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * 3D Viewer [[http:// | ||
+ | * MultistackReg [[http:// | ||
====== Discussions? | ====== Discussions? |
documents/120206pyip_cooking/python_imagej_cookbook.1481199067.txt.gz · Last modified: 2016/12/08 12:11 by kota