def main(): Interpreter.batchMode = True if (lambda_flat == 0) ^ (lambda_dark == 0): print ("ERROR: Both of lambda_flat and lambda_dark must be zero," " or both non-zero.") return lambda_estimate = "Automatic" if lambda_flat == 0 else "Manual" print "Loading images..." options = ImporterOptions() options.setId(str(filename)) options.setOpenAllSeries(True) options.setConcatenate(True) options.setSplitChannels(True) imps = BF.openImagePlus(options) num_channels = len(imps) w = imps[0].getWidth() h = imps[0].getHeight() ff_imp = IJ.createImage("Flat-field", w, h, num_channels, 32); df_imp = IJ.createImage("Dark-field", w, h, num_channels, 32); basic = Basic() Basic_noOfSlices = Basic.getDeclaredField('noOfSlices') Basic_noOfSlices.setAccessible(True) for channel, imp in enumerate(imps): title = imp.getTitle() print "Processing:", title x, y, c, z, t = imp.getDimensions() assert z == 1 and c == 1 imp.setDimensions(1, t, 1) WindowManager.setTempCurrentImage(imp) Basic_noOfSlices.setInt(basic, t) basic.exec( imp, None, None, "Estimate shading profiles", "Estimate both flat-field and dark-field", lambda_estimate, lambda_flat, lambda_dark, "Ignore", "Compute shading only" ) ff_channel = WindowManager.getImage('Flat-field:' + title) ff_channel.copy() ff_imp.setSlice(channel + 1) ff_imp.paste() ff_channel.close() df_channel = WindowManager.getImage('Dark-field:' + title) df_channel.copy() df_imp.setSlice(channel + 1) df_imp.paste() df_channel.close() imp.close() # Setting the active slice back to 1 seems to fix an issue where # the last slice was empty in the saved TIFFs. Not sure why. ff_imp.setSlice(1) df_imp.setSlice(1) ff_filename = '%s/%s-ffp-basic.tif' % (output_dir, experiment_name) IJ.saveAsTiff(ff_imp, ff_filename) ff_imp.show() ff_imp.close() df_filename = '%s/%s-dfp-basic.tif' % (output_dir, experiment_name) IJ.saveAsTiff(df_imp, df_filename) df_imp.show() df_imp.close() print "Done!"
def readCZI(imagefile, metainfo, stitchtiles=False, setflatres=False, readpylevel=0, setconcat=False, openallseries=True, showomexml=False, attach=False, autoscale=True): options = DynamicMetadataOptions() options.setBoolean("zeissczi.autostitch", stitchtiles) options.setBoolean("zeissczi.attachments", attach) czireader = ZeissCZIReader() czireader.setFlattenedResolutions(setflatres) czireader.setMetadataOptions(options) czireader.setId(imagefile) # Set the preferences in the ImageJ plugin # Note although these preferences are applied, they are not refreshed in the UI Prefs.set("bioformats.zeissczi.allow.autostitch", str(stitchtiles).lower()) Prefs.set("bioformats.zeissczi.include.attachments", str(attach).lower()) # metainfo = {} metainfo['rescount'] = czireader.getResolutionCount() metainfo['SeriesCount_CZI'] = czireader.getSeriesCount() metainfo['flatres'] = czireader.hasFlattenedResolutions() # metainfo['getreslevel'] = czireader.getResolution() # Dimensions metainfo['SizeT'] = czireader.getSizeT() metainfo['SizeZ'] = czireader.getSizeZ() metainfo['SizeC'] = czireader.getSizeC() metainfo['SizeX'] = czireader.getSizeX() metainfo['SizeY'] = czireader.getSizeY() # check for autostitching and possibility to read attachment metainfo['AllowAutoStitching'] = czireader.allowAutostitching() metainfo['CanReadAttachments'] = czireader.canReadAttachments() # read in and display ImagePlus(es) with arguments options = ImporterOptions() options.setOpenAllSeries(openallseries) options.setShowOMEXML(showomexml) options.setConcatenate(setconcat) options.setAutoscale(autoscale) options.setId(imagefile) # open the ImgPlus imps = BF.openImagePlus(options) metainfo['Pyramid Level Output'] = readpylevel # read image data using the specified pyramid level imp, slices, width, height, pylevel = ImageTools.getImageSeries(imps, series=readpylevel) metainfo['Pyramid Level Output'] = pylevel metainfo['Output Slices'] = slices metainfo['Output SizeX'] = width metainfo['Output SizeY'] = height # calc scaling in case of pyramid # scale = float(metainfo['Output SizeX']) / float(metainfo['SizeX']) scale = float(metainfo['SizeX']) / float(metainfo['Output SizeX']) metainfo['Pyramid Scale Factor'] = scale metainfo['ScaleX Output'] = metainfo['ScaleX'] * scale metainfo['ScaleY Output'] = metainfo['ScaleY'] * scale """ imp = MiscTools.setproperties(imp, scaleX=metainfo['ScaleX Output'], scaleY=metainfo['ScaleX Output'], scaleZ=metainfo['ScaleZ'], unit="micron", sizeC=metainfo['SizeC'], sizeZ=metainfo['SizeZ'], sizeT=metainfo['SizeT']) """ imp = MiscTools.setscale(imp, scaleX=metainfo['ScaleX Output'], scaleY=metainfo['ScaleX Output'], scaleZ=metainfo['ScaleZ'], unit="micron") # close czireader czireader.close() return imp, metainfo
def process_time_points(root, files, outdir): '''Concatenate images and write ome.tiff file. If image contains already multiple time points just copy the image''' concat = 1 files.sort() options = ImporterOptions() options.setId(files[0]) options.setVirtual(1) image = BF.openImagePlus(options) image = image[0] if image.getNFrames() > 1: IJ.log(files[0] + " Contains multiple time points. Can only concatenate single time points! Don't do anything!") image.close() return width = image.getWidth() height = image.getHeight() for patt in pattern: outName = re.match(patt, os.path.basename(files[0])) if outName is None: continue if outdir is None: outfile = os.path.join(root, outName.group(1) + '.ome.tif') else: outfile = os.path.join(outdir, outName.group(1) + '.ome.tif') reader = ImageReader() reader.setMetadataStore(MetadataTools.createOMEXMLMetadata()) reader.setId(files[0]) timeInfo = [] omeOut = reader.getMetadataStore() omeOut = setUpXml(omeOut, image, files) reader.close() image.close() IJ.log ('Concatenates ' + os.path.join(root, outName.group(1) + '.ome.tif')) itime = 0 try: for ifile, fileName in enumerate(files): print fileName omeMeta = MetadataTools.createOMEXMLMetadata() reader.setMetadataStore(omeMeta) reader.setId(fileName) #print omeMeta.getPlaneDeltaT(0,0) #print omeMeta.getPixelsTimeIncrement(0) if fileName.endswith('.czi'): if ifile == 0: T0 = omeMeta.getPlaneDeltaT(0,0).value() dT = omeMeta.getPlaneDeltaT(0,0).value() - T0 unit = omeMeta.getPlaneDeltaT(0,0).unit() else: timeInfo.append(getTimePoint(reader, omeMeta)) unit = omeMeta.getPixelsTimeIncrement(0).unit() try: dT = round(timeInfo[files.index(fileName)]-timeInfo[0],2) except: dT = (timeInfo[files.index(fileName)]-timeInfo[0]).seconds nrImages = reader.getImageCount() for i in range(0, reader.getImageCount()): try: omeOut.setPlaneDeltaT(dT, 0, i + itime*nrImages) except TypeError: omeOut.setPlaneDeltaT(Time(dT, unit),0, i + itime*nrImages) omeOut.setPlanePositionX(omeOut.getPlanePositionX(0,i), 0, i + itime*nrImages) omeOut.setPlanePositionY(omeOut.getPlanePositionY(0,i), 0, i + itime*nrImages) omeOut.setPlanePositionZ(omeOut.getPlanePositionZ(0,i), 0, i + itime*nrImages) omeOut.setPlaneTheC(omeOut.getPlaneTheC(0,i), 0, i + itime*nrImages) omeOut.setPlaneTheT(NonNegativeInteger(itime), 0, i + itime*nrImages) omeOut.setPlaneTheZ(omeOut.getPlaneTheZ(0,i), 0, i + itime*nrImages) itime = itime + 1 reader.close() IJ.showProgress(files.index(fileName), len(files)) try: incr = float(dT/(len(files)-1)) except: incr = 0 try: omeOut.setPixelsTimeIncrement(incr, 0) except TypeError: #new Bioformats >5.1.x omeOut.setPixelsTimeIncrement(Time(incr, unit),0) outfile = concatenateImagePlus(files, outfile) if outfile is not None: filein = RandomAccessInputStream(outfile) fileout = RandomAccessOutputStream(outfile) saver = TiffSaver(fileout, outfile) saver.overwriteComment(filein,omeOut.dumpXML()) fileout.close() filein.close() except: traceback.print_exc() finally: #close all possible open files try: reader.close() except: pass try: filein.close() except: pass try: fileout.close() except:
def readczi(imagefile, stitchtiles=True, setflatres=False, readpylevel=0, setconcat=True, openallseries=True, showomexml=False, attach=False, autoscale=True): log.log(LogLevel.INFO, 'Filename : ' + imagefile) metainfo = {} # checking for thr file Extension metainfo['Extension'] = MiscTools.getextension(MiscTools.splitext_recurse(imagefile)) log.log(LogLevel.INFO, 'Detected File Extension : ' + metainfo['Extension']) # initialize the reader and get the OME metadata reader = ImageReader() omeMeta = MetadataTools.createOMEXMLMetadata() #metainfo['ImageCount_OME'] = omeMeta.getImageCount() reader.setMetadataStore(omeMeta) reader.setId(imagefile) metainfo['SeriesCount_BF'] = reader.getSeriesCount() reader.close() # get the scaling for XYZ physSizeX = omeMeta.getPixelsPhysicalSizeX(0) physSizeY = omeMeta.getPixelsPhysicalSizeY(0) physSizeZ = omeMeta.getPixelsPhysicalSizeZ(0) if physSizeX is not None: metainfo['ScaleX'] = round(physSizeX.value(), 3) metainfo['ScaleY'] = round(physSizeX.value(), 3) if physSizeX is None: metainfo['ScaleX'] = None metainfo['ScaleY'] = None if physSizeZ is not None: metainfo['ScaleZ'] = round(physSizeZ.value(), 3) if physSizeZ is None: metainfo['ScaleZ'] = None options = DynamicMetadataOptions() options.setBoolean("zeissczi.autostitch", stitchtiles) options.setBoolean("zeissczi.attachments", attach) czireader = ZeissCZIReader() czireader.setFlattenedResolutions(setflatres) czireader.setMetadataOptions(options) czireader.setId(imagefile) # Set the preferences in the ImageJ plugin # Note although these preferences are applied, they are not refreshed in the UI Prefs.set("bioformats.zeissczi.allow.autostitch", str(stitchtiles).lower()) Prefs.set("bioformats.zeissczi.include.attachments", str(attach).lower()) # metainfo = {} metainfo['rescount'] = czireader.getResolutionCount() metainfo['SeriesCount_CZI'] = czireader.getSeriesCount() #metainfo['flatres'] = czireader.hasFlattenedResolutions() #metainfo['getreslevel'] = czireader.getResolution() # Dimensions metainfo['SizeT'] = czireader.getSizeT() metainfo['SizeZ'] = czireader.getSizeZ() metainfo['SizeC'] = czireader.getSizeC() metainfo['SizeX'] = czireader.getSizeX() metainfo['SizeY'] = czireader.getSizeY() # check for autostitching and possibility to read attachment metainfo['AllowAutoStitching'] = czireader.allowAutostitching() metainfo['CanReadAttachments'] = czireader.canReadAttachments() # read in and display ImagePlus(es) with arguments options = ImporterOptions() options.setOpenAllSeries(openallseries) options.setShowOMEXML(showomexml) options.setConcatenate(setconcat) options.setAutoscale(autoscale) options.setId(imagefile) # open the ImgPlus imps = BF.openImagePlus(options) metainfo['Pyramid Level Output'] = readpylevel + 1 try: imp = imps[readpylevel] pylevelout = metainfo['SeriesCount_CZI'] except: # fallback option log.log(LogLevel.INFO, 'PyLevel=' + str(readpylevel) + ' does not exist.') log.log(LogLevel.INFO, 'Using Pyramid Level = 0 as fallback.') imp = imps[0] pylevelout = 0 metainfo['Pyramid Level Output'] = pylevelout # get the stack and some info imgstack = imp.getImageStack() metainfo['Output Slices'] = imgstack.getSize() metainfo['Output SizeX'] = imgstack.getWidth() metainfo['Output SizeY'] = imgstack.getHeight() # calc scaling in case of pyramid scale = float(metainfo['SizeX']) / float(metainfo['Output SizeX']) metainfo['Pyramid Scale Factor'] = scale metainfo['ScaleX Output'] = metainfo['ScaleX'] * scale metainfo['ScaleY Output'] = metainfo['ScaleY'] * scale # set the correct scaling imp = MiscTools.setscale(imp, scaleX=metainfo['ScaleX Output'], scaleY=metainfo['ScaleX Output'], scaleZ=metainfo['ScaleZ'], unit="micron") # close czireader czireader.close() return imp, metainfo
# using the 'triangle' algorithm. It then uses the threshold to calculate the mean intensity above the # threshold. # # First version : 2017.09.14 from loci.plugins import BF from loci.formats import ImageReader from loci.plugins.in import ImporterOptions from ij.plugin import ZProjector from ij.process import AutoThresholder,ImageStatistics from math import isnan from ij import IJ # Open all files in the series options = ImporterOptions() options.setOpenAllSeries(True) options.setId(file.absolutePath) options.setQuiet(True) imps = BF.openImagePlus(options) # Initialize XML and arrays where to store the values xml = '<?xml version="1.0" encoding="utf-8"?><DyeData>' profiles=[] names=[] for idye_,imp in enumerate(imps): idye = idye_+1 # Assumes names are FILENAME+" - "+SERIESNAME names.append(imp.title.split(" - ")[1])
def bfopenall(path): options = ImporterOptions(); options.setId(path); options.setOpenAllSeries(True); return BF.openImagePlus(options);
def imageprojector(channels, timelist_unsorted, dirs): """ Projects .lif timepoints and saves in a common directory, as well as channel separated directories. """ # Defines in path path = str(Experiment) # BF Importer options = ImporterOptions() try: options.setId(path) except Exception(e): print str(e) options.setOpenAllSeries(True) options.setSplitTimepoints(True) options.setSplitChannels(True) imps = BF.openImagePlus(options) timelist = [x for item in timelist_unsorted for x in repeat(item, channels)] timelist, imps = zip(*sorted(zip(timelist, imps))) counter_C0 = -1 counter_C1 = -1 counter_C2 = -1 # Opens all images, splits channels, z-projects and saves to disk for imp in (imps): # Projection, Sum Intensity project = ZProjector() project.setMethod(ZProjector.SUM_METHOD) project.setImage(imp) project.doProjection() impout = project.getProjection() projection = impout.getTitle() try: # Saves channels to disk, # add more channels here if desired, # remember to define new counters. if "C=0" in projection: counter_C0 += 1 IJ.saveAs(impout, "TIFF", os.path.join(dirs["Projections"], "Scan" + str(counter_C0).zfill(3) + "C0")) IJ.saveAs(impout, "TIFF", os.path.join(dirs["Projections_C0"], "Scan" + str(counter_C0).zfill(3) + "C0")) elif "C=1" in projection: counter_C1 += 1 IJ.saveAs(impout, "TIFF", os.path.join(dirs["Projections"], "Scan" + str(counter_C1).zfill(3) + "C1")) IJ.saveAs(impout, "TIFF", os.path.join(dirs["Projections_C1"], "Scan" + str(counter_C1).zfill(3) + "C1")) elif "C=2" in projection: counter_C2 += 1 IJ.saveAs(impout, "TIFF", os.path.join(dirs["Projections"], "Scan" + str(counter_C2).zfill(3) + "C2")) IJ.saveAs(impout, "TIFF", os.path.join(dirs["Projections_C2"], "Scan" + str(counter_C2).zfill(3) + "C2")) except IOException: print "Directory does not exist" raise IJ.log("Images projected and saved to disk")
def getCZIinfo(imagefile, showimage=False, setreslevel=0, setflat2=False, openallseries=True, showomexml=False,setconcat=False,filepath1="./"): options = DynamicMetadataOptions() options.setBoolean("zeissczi.attachments", False) czireader = ZeissCZIReader() czireader.setFlattenedResolutions(setflat2) czireader.setMetadataOptions(options) czireader.setId(imagefile) lc = czireader.getSeriesCount() #get the first occurence of each pyramid stack location=list() for i in range(0, int(seriesCount)-2): location.append(czireader.coreIndexToSeries(i)) c=0 #log.info(location) loc2=list() for i,v in enumerate(location): if i==0: loc2.append(i) elif i>0 and v!=c: loc2.append(i) c=v log.info(str(loc2)) # get OME data omeMeta = MetadataTools.createOMEXMLMetadata() # Set the preferences in the ImageJ plugin Prefs.set("bioformats.zeissczi.include.attachments", str(True).lower()) if showimage: # read in and display ImagePlus(es) with arguments options = ImporterOptions() options.setOpenAllSeries(openallseries) options.setShowOMEXML(showomexml) options.setConcatenate(setconcat) options.setId(imagefile) # open the ImgPlus imps = BF.openImagePlus(options) name_list=imagefile.split('/') name=name_list[len(name_list)-1] out_path=filepath1 + "/"+name+"_Preview.tif" log.info(name) imp=getImageSeries(imps, seriesCount-1) imp.show() IJ.run("RGB Color") imp.close() IJ.saveAs("tiff", out_path) IJ.run("Close") out_path=filepath1 + "/"+name+"_Label.tif" imp=getImageSeries(imps, (seriesCount-2)) imp.show() IJ.run("RGB Color") imp.close() IJ.saveAs("tiff", out_path) IJ.run("Close") c=1 for series in loc2: out_path=filepath1 + "/"+name+"Scene_" + str(c) + ".tif" imp=getImageSeries(imps, series) imp.show() IJ.run("RGB Color") imp.close() IJ.saveAs("tiff", out_path) IJ.run("Close") c+=1 czireader.close()
def main(): Interpreter.batchMode = True if (lambda_flat == 0) ^ (lambda_dark == 0): print ("ERROR: Both of lambda_flat and lambda_dark must be zero," " or both non-zero.") return lambda_estimate = "Automatic" if lambda_flat == 0 else "Manual" print "Loading images..." # For multi-scene .CZI files, we need raw tiles instead of the # auto-stitched mosaic and we don't want labels or overview images. This # only affects BF.openImagePlus, not direct use of the BioFormats reader # classes which we also do (see below) Prefs.set("bioformats.zeissczi.allow.autostitch", "false") Prefs.set("bioformats.zeissczi.include.attachments", "false") # Use BioFormats reader directly to determine dataset dimensions without # reading every single image. The series count (num_images) is the one value # we can't easily get any other way, but we might as well grab the others # while we have the reader available. dyn_options = DynamicMetadataOptions() # Directly calling a BioFormats reader will not use the IJ Prefs settings # so we need to pass these options explicitly. dyn_options.setBoolean("zeissczi.autostitch", False) dyn_options.setBoolean("zeissczi.attachments", False) bfreader = ImageReader() bfreader.setMetadataOptions(dyn_options) bfreader.id = str(filename) num_images = bfreader.seriesCount num_channels = bfreader.sizeC width = bfreader.sizeX height = bfreader.sizeY bfreader.close() # The internal initialization of the BaSiC code fails when we invoke it via # scripting, unless we explicitly set a the private 'noOfSlices' field. # Since it's private, we need to use Java reflection to access it. Basic_noOfSlices = Basic.getDeclaredField('noOfSlices') Basic_noOfSlices.setAccessible(True) basic = Basic() Basic_noOfSlices.setInt(basic, num_images) # Pre-allocate the output profile images, since we have all the dimensions. ff_image = IJ.createImage("Flat-field", width, height, num_channels, 32); df_image = IJ.createImage("Dark-field", width, height, num_channels, 32); print("\n\n") # BaSiC works on one channel at a time, so we only read the images from one # channel at a time to limit memory usage. for channel in range(num_channels): print "Processing channel %d/%d..." % (channel + 1, num_channels) print "===========================" options = ImporterOptions() options.id = str(filename) options.setOpenAllSeries(True) # concatenate=True gives us a single stack rather than a list of # separate images. options.setConcatenate(True) # Limit the reader to the channel we're currently working on. This loop # is mainly why we need to know num_images before opening anything. for i in range(num_images): options.setCBegin(i, channel) options.setCEnd(i, channel) # openImagePlus returns a list of images, but we expect just one (a # stack). input_image = BF.openImagePlus(options)[0] # BaSiC seems to require the input image is actually the ImageJ # "current" image, otherwise it prints an error and aborts. WindowManager.setTempCurrentImage(input_image) basic.exec( input_image, None, None, "Estimate shading profiles", "Estimate both flat-field and dark-field", lambda_estimate, lambda_flat, lambda_dark, "Ignore", "Compute shading only" ) input_image.close() # Copy the pixels from the BaSiC-generated profile images to the # corresponding channel of our output images. ff_channel = WindowManager.getImage("Flat-field:%s" % input_image.title) ff_image.slice = channel + 1 ff_image.getProcessor().insert(ff_channel.getProcessor(), 0, 0) ff_channel.close() df_channel = WindowManager.getImage("Dark-field:%s" % input_image.title) df_image.slice = channel + 1 df_image.getProcessor().insert(df_channel.getProcessor(), 0, 0) df_channel.close() print("\n\n") template = '%s/%s-%%s.tif' % (output_dir, experiment_name) ff_filename = template % 'ffp' IJ.saveAsTiff(ff_image, ff_filename) ff_image.close() df_filename = template % 'dfp' IJ.saveAsTiff(df_image, df_filename) df_image.close() print "Done!"