User Tools

Site Tools


documents:120206pyip_cooking:python_imagej_cookbook

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
documents:120206pyip_cooking:python_imagej_cookbook [2018/11/23 02:28] – [Getting path to a file interactively] kotadocuments: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://www.ini.uzh.ch/~acardona/fiji-tutorial/ | here in his website]] or [[https://imagej.net/Jython_Scripting | here in ImageJ.net]]. The former is in a tutorial style so if you want to learn how to do scripting using Jython, that's the place where you go. Recently, there is a very good tutorial page for real beginners: [[https://learning.rc.virginia.edu/notes/fiji-scripting/|here (UVA Research Computing Learning Portal).]]  
 +
 +This page is like a cookbook: there are no details about how to do programming, but more centered on how to use Classes built in ImageJ and its plugins. This is because the style how each algorithm is implemented is not consistent (they are written by 1000 different people!) so it takes a while to figure out how to use them when we are writing a bioimage analysis workflow. Examples below show how they are actually used in Jython scripts, to save our time for reading the source code of each. 
 +
 +Other resources: 
 +
 +[[https://jython.readthedocs.io/en/latest/|The Jython book "The Definitive Guide to Jython"]]: it's saying that the book is a version from 2009, but the latest commit is in Oct. 2018. 
 ===== Jython Interpreter ===== ===== Jython Interpreter =====
 A way to run jython script from jython interpreter, interactively. A way to run jython script from jython interpreter, interactively.
Line 84: Line 91:
 for j in range(imp.getHeight()): for j in range(imp.getHeight()):
  
 +</code>
 +
 +===== ImageJ2 / SciJava =====
 +
 +==== Running a script from another script ====
 +
 +<code python>
 +#@ ScriptService scriptService
 +
 +fullscript = "#@ String A_STRING\n" + \
 +"#@ Boolean (label='An Option', value=true) OPTION"
 +
 +scriptmodule = scriptService.run(".py", fullscript, True).get()
 +scriptInputmaps = scriptmodule.getInputs()
 +
 +print scriptmodule.getOutputs()
 +print scriptInputmaps
 +# how can we know the dialog was Canceled?
 +print scriptmodule.isInputResolved('A_STRING')
 </code> </code>
  
Line 103: Line 129:
 print imp.getOriginalFileInfo().directory print imp.getOriginalFileInfo().directory
 </code> </code>
 +
 +... can also be done by ''%%IJ.getDirectory("image")%%'', but with this IJ method, one cannot specify target ImagePlus object. See also the [[https://github.com/imagej/imagej1/blob/master/ij/IJ.java#L1652-L1663|source code of IJ.getDirectory]]
 +
 +Be careful not to mix with the usage of ''%%getFileInfo%%''. This does not hold directory information. 
 +
 +
 ==== Regular Expression to get meta information from file name ==== ==== Regular Expression to get meta information from file name ====
  
Line 210: Line 242:
 </code> </code>
  
 +Fiji comes with ApacheIO library, and can be used quite conveniently for disintegrating file paths. See [[https://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/FilenameUtils.html|Javadoc]] for many other convenient methods. 
 +<code python linenums:1>
 +from org.apache.commons.io import FilenameUtils
 +
 +srcpath = '/Users/miura/tmp/data.csv'
 +
 +
 +baseName = FilenameUtils.getBaseName(srcpath)
 +print "Basename: ", baseName
 +
 +ext = FilenameUtils.getExtension(srcpath)
 +print "Extension: ", ext
 +
 +filename = FilenameUtils.getName(srcpath)
 +print "File name: ", filename
 +
 +pathWOext = FilenameUtils.removeExtension(srcpath)
 +print "Fullpath without ext: ", pathWOext
 +
 +# outputs
 +#
 +# Basename:  data
 +# Extension:  csv
 +# File name:  data.csv
 +# Fullpath without ext:  /Users/miura/tmp/data
 +</code>
 +
 +
 +
 +==== Loading a textfile as String ====
 +
 +<code python linenums:1>
 +path = "/Users/miura/data.txt"
 +with open(inpath, 'r') as myfile:
 +  data = myfile.read()
 +print data
 +</code>
 +
 +==== Saving String as a textfile ====
 +
 +<code python linenums:1>
 +with open("/Users/miura/Downloads/testOutput.txt", "w") as text_file:
 +    text_file.write("The first line\nAnother line"   
 +text_file.close()
 +</code>
 ==== Loading CSV file ==== ==== Loading CSV file ====
  
Line 544: Line 621:
 </code> </code>
  
 +==== 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("red", 0.6)
 +amap.put("green", 1)
 +amap.put("blue", 0.3)
 +jo = JSONObject(amap)
 +print str(jo)
 +</code>
 +
 +This code yields:
 +<code>
 +{"blue":0.3,"green":1,"red":0.6}
 +</code>
 +
 +==== Generating Time Stamp String ====
 +
 +<code python>
 +from java.util import Date
 +from java.text import SimpleDateFormat
 +
 +timeStamp = SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(Date())
 +print timeStamp
 +</code>
  
 ===== Arrays (Lists) ===== ===== Arrays (Lists) =====
Line 550: Line 658:
  
 We first start with Python list (or for me is "python array"):   We first start with Python list (or for me is "python array"):  
-==== Concatenate Arrays ====+==== Appending Elements to a List ==== 
 + 
 +Two ways to append an element to a list.  
 +<code:py> 
 +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] 
 + 
 +</code> 
 +==== Concatenate lists ====
 <code python linenums:1> <code python linenums:1>
 a = [1, 2, 3] a = [1, 2, 3]
Line 601: Line 732:
 imgarray = jarray.array([imp1, imp2], ImagePlus) imgarray = jarray.array([imp1, imp2], ImagePlus)
 colorimp = RGBStackMerge().mergeHyperstacks(imgarray, False)  colorimp = RGBStackMerge().mergeHyperstacks(imgarray, False) 
 +</code>
 +
 +==== 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. 
 +
 +<code:py> 
 +from ij.process import StackStatistics
 +import jarray
 +
 +stackstats = StackStatistics(imp)
 +histD = stackstats.histogram()
 +hist = jarray.zeros(len(histD), 'i')
 +for i in range(len(histD)):
 +    hist[i] = int(histD[i])
 </code> </code>
  
Line 641: 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://stackoverflow.com/questions/45417732/jython-function-to-java-consumer|here]]. For the Java Stream API, this page is useful: [[https://www.baeldung.com/java-8-streams|The Java 8 Stream API Tutorial]]
 +
 +<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, fn):
 +        self.accept=fn
 +
 +class jf(Function):
 +    def __init__(self, fn):
 +        self.apply = fn
 +
 +class jp(Predicate):
 +    def __init__(self, fn):
 +        self.test = fn
 +        
 +def jprint(x):
 + print x
 +
 +tt = ["a", "b", "c"]
 +c = Arrays.stream(tt).count()
 +print c
 +
 +print "forEach printing"
 +Arrays.stream(tt).forEach(jc(lambda x: jprint("="+x)))
 +
 +print "forEach printing parallelly"
 +Arrays.stream(tt).parallel().forEach(jc(lambda x: jprint("="+x)))
 +
 +print "has b?", Arrays.stream(tt).anyMatch(jp(lambda x: x=="b"))
 +print "has z?", Arrays.stream(tt).anyMatch(jp(lambda x: x=="z"))
 +
 +# convert to Java List<>
 +jtt = Arrays.asList(tt)
 +
 +jtt.stream().forEach(jc(lambda x: jprint("+"+x)))
 +</code>
 ===== Event Listener ===== ===== Event Listener =====
  
Line 693: Line 883:
 </code> </code>
  
 +===== 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("start")
 +wud = WaitForUserDialog("test: wait for user", "Click OK if you are done with your manual work")
 +print("waiting...")
 +wud.show()
 +print("done")
 +</code>
  
 ===== HashMap ===== ===== HashMap =====
Line 822: Line 1025:
 outimp.show() outimp.show()
 </code> </code>
 +
 +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()
 +</code>
 +
  
 ==== Threshold to create a mask (Binary) ==== ==== Threshold to create a mask (Binary) ====
Line 855: Line 1080:
 maskimp.show() maskimp.show()
 </code> </code>
 +
 +=== 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. 
 +
 +<code>
 +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("http://imagej.nih.gov/ij/images/confocal-series.zip")
 +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, "Grays", "");
 +imp1bin.show()
 +</code>
 +
 +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("http://imagej.nih.gov/ij/images/confocal-series.zip")
 +#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 "pixvalue range:", pixmin, " - " ,pixmax
 + 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), bp)
 +
 +binimp = ImagePlus("bin", binstack)
 +binimp.show()
 +</code>
 +
  
 ==== ROI manager ==== ==== ROI manager ====
Line 901: Line 1199:
  istats = ip.getStatistics()  istats = ip.getStatistics()
  print istats.mean  print istats.mean
 +</code>
 +
 +=== Saving All ROIs as a single zip file ===
 +
 +<code py>
 +import os, jarray
 +from ij.plugins.frame.RoiManager
 +
 +outdir = "/Users/miura/Downloads"
 +roizipname = "myROIs.zip"
 +roizippath = os.path.join(outdir, roizipname)
 +rm = RoiManager.getInstance()
 +if rm.getCount() > 0:
 +    roiindex = jarray.array(range(0, rm.getCount()), 'i')
 +    rm.setSelectedIndexes(roiindex)
 +    rm.runCommand('Save', roizippath)
 </code> </code>
  
Line 930: Line 1244:
 boundroi = ThresholdToSelection.run(segimp) boundroi = ThresholdToSelection.run(segimp)
 rm.addRoi(boundroi) rm.addRoi(boundroi)
 +</code>
 +
 +==== Adding Overlay in 3D Stack (ROI to Overlay) ====
 +
 +<code:py>
 +from ij import IJ
 +from ij.gui import OvalRoi, Overlay
 +
 +imp = IJ.getImage()
 +roi = OvalRoi(170, 160, 22, 22)
 +roi.setPosition(19)
 +
 +ol = Overlay()
 +ol.add(roi)
 +imp.setOverlay(ol)
 +ol.setStrokeWidth(2) 
 </code> </code>
  
Line 1105: Line 1435:
 print "pixval=", pixval, " count:", count print "pixval=", pixval, " count:", count
 </code> </code>
 +
 +==== 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:1>
 +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, 301, 4)
 + # green channel = 2
 + ip.setMinAndMax(29, 80, 2)
 + # blue channel = 1
 + ip.setMinAndMax(29, 80, 1)
 +imp.updateAndDraw()
 +</code>
 +
  
 ==== Translation of 3D image using ImgLib2 ==== ==== Translation of 3D image using ImgLib2 ====
Line 1211: Line 1562:
  
 For more explanation about this processing, see [[http://rsbweb.nih.gov/ij/developer/api/ij/plugin/filter/GaussianBlur.html|the explanation in javadoc]]. For more explanation about this processing, see [[http://rsbweb.nih.gov/ij/developer/api/ij/plugin/filter/GaussianBlur.html|the explanation in javadoc]].
 +
 +==== 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, radius, createBackground, lightBackground, useParaboloid, doPresmooth, correctCorners)
 +imp.updateAndDraw()
 +</code>
 +
 +If the image is in RGB, then use a different method (rollingBallBrightnessBackground​).
 +
 +For more explanation about this processing, see [[https://imagej.nih.gov/ij/developer/api/ij/ij/plugin/filter/BackgroundSubtracter.html|the explanation in javadoc]].
 ==== ImageCalculator ==== ==== ImageCalculator ====
  
Line 1571: Line 1949:
 fullimps[0].show() fullimps[0].show()
 </code> </code>
 +
 +If you do not want to open all images (called sereies) in multi-image CZI files, replace 
 +<code>
 +open.setOpenAllSeries(True) 
 +</code>
 +with 
 +<code>
 +options.setSeriesOn(seriesIndex, True)
 +</code>
 +with "sereiesIndex" being the seriesID e.g. 1 or 2 or 3 ... 
  
 See here for more on metadata parsing and so on: [[https://gist.github.com/ctrueden/6282856|bio-formats.py]] See here for more on metadata parsing and so on: [[https://gist.github.com/ctrueden/6282856|bio-formats.py]]
 +
 +==== 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:1>
 +from loci.formats import ImageReader
 +
 +r = ImageReader()
 +filepath = '/to/my.czi'
 +r.setId( filepath )
 +print r.getSeriesCount()
 +</code>
  
 ==== Replacing OME-TIFF XML ==== ==== Replacing OME-TIFF XML ====
Line 1719: 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 1750: Line 2154:
  classifiedImage = weka.getClassifiedImage()  classifiedImage = weka.getClassifiedImage()
  classifiedImage.show()  classifiedImage.show()
 +</code>
 +
 +==== 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 = '/ARFFdata/'
 +data1path = pp+ 'data1.arff'
 +data2path = pp+ 'data2.arff'
 +
 +data1 = ConverterUtils.DataSource.read(data1path)
 +data2 = ConverterUtils.DataSource.read(data2path)
 +print "data1: ", data1.size()
 +print "data2: ", data2.size()
 +
 +for i in range(data2.size()):
 + data1.add(data2.get(i))
 +
 +dataMerged = data1
 +print "Merged: ", dataMerged.size()
 +
 +# if data1 and data2 have the same size, the line below can be used. 
 +#dataMerged = Instances.mergeInstances(data1, data2)
 +
 +dataMargedPath = pp + "dataMerged.arff"
 +
 +ConverterUtils.DataSink.write(dataMargedPath, dataMerged )
 +</code>
 +
 +==== Merging ARFF data files in another way, train and apply classifier ====
 +
 +<code python>
 +from trainableSegmentation import WekaSegmentation
 +from ij import IJ
 +
 +# == merging
 +
 +pp = '/ARFFdata/'
 +data1path = pp+ 'data1.arff'
 +data2path = pp+ 'data2.arff'
 +
 +ws = WekaSegmentation()
 +data1 = ws.readDataFromARFF(data1path)
 +data2 = ws.readDataFromARFF(data2path)
 +ws.mergeDataInPlace(data1, data2) #this concatenates data2 to data2
 +dataBalanced = WekaSegmentation.balanceTrainingData(data1) #optional: can balance the classes
 +ws.setLoadedTrainingData(dataBalanced)
 +
 +dataOutpath = pp+ 'dataBalanced.arff'
 +ws.writeDataToARFF(dataBalanced, dataOutpath)
 +
 +# == now train and apply a classifier to an image
 +
 +if ws.trainClassifier():
 + imp = IJ.getImage()
 + classifiedImage = ws.applyClassifier(imp, 0, True)
 + classifiedImage.show()
 +
 </code> </code>
  
Line 1893: Line 2359:
     print p, resmap.get(p)     print p, resmap.get(p)
 </code> </code>
 +
 +===== Plugin: MiToBo h-dome transformation =====
 +
 +h-dome is useful for spot detection in a noisy background. [[https://www.researchgate.net/publication/261206082_A_new_approach_for_spot_detection_in_total_internal_reflection_fluorescence_microscopy | For example, see this reference]]. The example here uses Plugin MiToBo, a huge collection of various components. 
 +
 +<code:py>
 +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, 10.0)
 +hdome.runOp()
 +mtbdone = hdome.getResultImage()
 +imp2 = mtbdone.getImagePlus()
 +imp2.show()
 +
 +</code>
 +
 +===== Plugin: MorphoLibJ =====
 +
 +Javadoc: [[http://ijpb.github.io/MorphoLibJ/javadoc/]]
 +==== Distance Transform Watershed 3D ====
 +
 +<code:py>
 +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(  ChamferWeights3D.BORGEFORS.toString() )
 +#weights = ChamferWeights3D.fromLabel(  "Borgefors (3,4,5)" )
 +weights = ChamferWeights3D.BORGEFORS.getShortWeights()
 +dist = BinaryImages.distanceMap( imp.getImageStack(),weights , normalize )
 +Images3D.invert( dist )
 +#public static final ImageStack extendedMinimaWatershed( ImageStack image, ImageStack mask, int dynamic, int connectivity, int outputType, boolean verbose )
 +# @param dynamic the maximum difference between the minima and the boundary of a basin
 +result = ExtendedMinimaWatershed.extendedMinimaWatershed(dist, imp.getImageStack(), dynamic, connectivity, 16, False )
 +outimp = ImagePlus( imp.getShortTitle() + "dist-watershed", result )
 +outimp.show()
 +</code>
 +
 +==== Connected Component 3D labeling ====
 +
 +<code:py>
 +from ij import IJ, ImagePlus
 +from inra.ijpb.binary import BinaryImages
 +
 +imp = IJ.getImage()
 +
 +connectivity = 6
 +outbitDepth = 16
 +outimp = BinaryImages.componentsLabeling(imp, connectivity, outbitDepth)
 +outimp.setTitle(imp.getShortTitle() + "-labeled")
 +outimp.show()
 +</code>
 +
 +==== 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("BorderKilled", newip)
 +newimp.show()
 +</code>
 +
 +===== 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://framagit.org/mcib3d/mcib3d-core/-/wikis/home|3D ImageJ Suite]]
 +
 +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://framagit.org/mcib3d/mcib3d-core|MCIB-Core source]]
 +  * [[https://framagit.org/mcib3d/mcib3d-plugins|MCIB-Plugins source]]
 +
 +The Javadoc I created (Core and Plugins are merged):
 +
 +  * [[https://wiki.cmci.info/mcib-javadoc/| MCIB3D Javadoc]]
 +
 +==== 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. 
 +
 +<code:py>
 +from ij import IJ, ImagePlus
 +from mcib3d.geom import ObjectCreator3D
 +from mcib3d.image3d import ImageHandler
 +
 +oc3d = ObjectCreator3D(200, 200, 50)
 +oc3d.createSphere(50, 50, 10, 3, 1, False)
 +oc3d.createSphere(50, 50, 20, 3, 2, False)
 +oc3d.createSphere(50, 50, 30, 3, 3, False)
 +
 +imp = oc3d.getPlus() 
 +#imp.show()
 +
 +obj1 = oc3d.getObject3DVoxels(1)
 +obj2 = oc3d.getObject3DVoxels(2)
 +obj3 = oc3d.getObject3DVoxels(3)
 + 
 +
 +impnew = IJ.createImage("Measured", 200,200, 50, 16)
 +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: ",obj2.getPixMeanValue(ima)
 +print "Obj3: ",obj3.getPixMeanValue(ima)
 +</code>
 +
 +
 ===== R: Multi-Peak fitting using R ===== ===== R: Multi-Peak fitting using R =====
  
Line 1990: Line 2589:
  
 See explanation in [[http://www.prasannatech.net/2008/09/implementing-java-interfaces-in-jython.html|here]].  See explanation in [[http://www.prasannatech.net/2008/09/implementing-java-interfaces-in-jython.html|here]]. 
 +
 +==== 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("\\n")
 + for ss in scan:
 + print ss
 +
 +
 +runShellCommand( "pwd" )
 +runShellCommand( "ls -la" )
 +</code>
 +
 +
 +==== Is docker daemon running? ====
 +
 +Check if the docker daemon is running ():
 +
 +<code python linenums:1>
 +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("\\n")
 + if not s.hasNext():
 + print "Please start docker desktop!"
 + return False
 + for ss in s:
 + print ss
 + if ss.startswith("CONTAINER ID"):
 + return True
 + else:
 + print "Please start docker desktop!"
 + return False
 +
 +# below is for OSX. WIth win, just "docker ps"
 +cmd = "/usr/local/bin/docker ps" 
 +if checkDockerRunning( cmd ):
 + print "Docker running"
 +else:
 + print "Docker not running"
 +</code>
 +
 +===== JAVADOCS =====
 +
 +  * 3D ImageJ Suite 
 +    * [[http://wiki.cmci.info/javaapi/mcib-javadoc/|JAVADOC]] (2019 version, deprecated)
 +    * [[https://wiki.cmci.info/mcib-javadoc/| MCIB3D Javadoc]] (2022 version)
 +    * [[https://github.com/mcib3d/mcib3d-core|Core Source (old)]] 
 +    * [[https://framagit.org/mcib3d/mcib3d-core|Core Source (2021-)]]
 +    * [[https://github.com/mcib3d/mcib3d-plugins|Plugin Source]]  
 +  * 3D Viewer [[http://wiki.cmci.info/javaapi/3Dprocessor/|JAVADOC]]
 +  * MultistackReg [[http://wiki.cmci.info/javaapi/multiStackReg_/|JAVADOC]]
  
 ====== Discussions? ====== ====== Discussions? ======
documents/120206pyip_cooking/python_imagej_cookbook.1542940115.txt.gz · Last modified: 2018/11/23 02:28 by kota

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki