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 revisionNext revisionBoth sides next revision | ||
documents:120206pyip_cooking:python_imagej_cookbook [2016/12/08 12:30] – [Export ROIs in RoiManager to a SVG file] kota | documents:120206pyip_cooking:python_imagej_cookbook [2022/10/16 06:35] – 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 Consumer interface. | ||
+ | |||
+ | <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), | ||
</ | </ | ||
Line 971: | 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 1071: | 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 1177: | 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 1301: | 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 1511: | 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 1656: | 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 1687: | 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 1730: | 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 1788: | 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 1805: | 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 1902: | 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.txt · Last modified: 2022/10/16 07:12 by kota