def test(img): imgT = TransformView.transformView(img, aff, interval, MultiViewDeconvolution.minValueImg, MultiViewDeconvolution.outsideValueImg, 1) # 1: linear interpolation imgA = ArrayImgs.floats(dimensions) ImgUtil.copy(ImgView.wrap(imgT, imgA.factory()), imgA)
def classify(img, classifier, class_names, ops=None, distribution_class_index=-1): """ img: a 2D RandomAccessibleInterval. classifier: a WEKA Classifier instance, like SMO or FastRandomForest, etc. Any. If it's a string, interprets it as a file path and attempts to deserialize a previously saved trained classifier. class_names: the list of names of each class to learn. ops: the filter bank of ImgMath ops for the img. distribution_class_index: defaults to -1, meaning return the class index for each pixel. When larger than -1, it's interpreted as a class index, and returns instead the floating-point value of each pixel in the distribution of that particular class index. """ if type(classifier) == str: classifier = SerializationHelper.read(classifier) ops = ops if ops else filterBank(img) attributes = ArrayList() for i in xrange(len(ops)): attributes.add(Attribute("attr-%i" % i)) #for name in classifier.attributeNames()[0][1]: # attributes.add(Attribute(name)) attributes.add(Attribute("class", class_names)) info = Instances("structure", attributes, 1) info.setClassIndex(len(attributes) -1) opImgs = [compute(op).into(ArrayImgs.floats([img.dimension(0), img.dimension(1)])) for op in ops] cs_opImgs = Views.collapse(Views.stack(opImgs)) result = ArrayImgs.floats([img.dimension(0), img.dimension(1)]) cr = result.cursor() cop = Views.iterable(cs_opImgs).cursor() while cr.hasNext(): tc = cop.next() vector = array((tc.get(i).getRealDouble() for i in xrange(len(opImgs))), 'd') vector += array([0], 'd') di = DenseInstance(1.0, vector) di.setDataset(info) # the list of attributes if distribution_class_index > -1: cr.next().setReal(classifier.distributionForInstance(di)[distribution_class_index]) else: cr.next().setReal(classifier.classifyInstance(di)) return result
def updatePixels(self): # Copy interval into pixels view = Views.interval( Views.extendZero(Views.hyperSlice(self.img3D, 2, self.indexZ)), self.interval2D) aimg = ArrayImgs.floats( self.getPixels(), [self.interval2D.dimension(0), self.interval2D.dimension(1)]) ImgUtil.copy(view, aimg)
def testJython(imgred, imggreen, imgblue): width, height = rgb.dimension(0), rgb.dimension(1) hb = zeros(width * height, 'f') sb = zeros(width * height, 'f') bb = zeros(width * height, 'f') cred = imgred.cursor() cgreen = imggreen.cursor() cblue = imgblue.cursor() i = 0 while cred.hasNext(): r = cred.next().getRealFloat() g = cgreen.next().getRealFloat() b = cblue.next().getRealFloat() cmax = max(r, g, b) cmin = min(r, g, b) bb[i] = cmax / 255.0 if 0 != cmax: sb[i] = (cmax - cmin) / cmax # Else leave sb[i] at zero if 0 == sb[i]: h = 0 else: span = cmax - cmin redc = (cmax - r) / span greenc = (cmax - g) / span bluec = (cmax - b) / span if r == cmax: h = bluec - greenc elif g == cmax: h = 2.0 + redc - bluec else: h = 4.0 + greenc - redc h /= 6.0 if h < 0: h += 1.0 hb[i] = h i += 1 hh = ArrayImgs.floats(hb, [width, height]) ss = ArrayImgs.floats(sb, [width, height]) bb = ArrayImgs.floats(bb, [width, height]) return Views.stack(hh, ss, bb)
def read2DImageROI(path, dimensions, interval, pixelType=UnsignedShortType, header=0, byte_order=ByteOrder.LITTLE_ENDIAN): """ Read a region of interest (the interval) of an image in a file. Assumes the image is written with the first dimension moving slowest. path: the file path to the image file. dimensions: a sequence of integer values e.g. [512, 512, 512] interval: two sequences of integer values defining the min and max coordinates, e.g. [[20, 0], [400, 550]] pixeltype: e.g. UnsignedShortType, FloatType header: defaults to zero, the number of bytes between the start of the file and the start of the image data. Supports only these types: UnsignedByteType, UnsignedShortType, FloatType. Returns an ArrayImg of the given type. """ ra = RandomAccessFile(path, 'r') try: width, height = dimensions minX, minY = interval[0] maxX, maxY = interval[1] roi_width, roi_height = maxX - minX + 1, maxY - minY + 1 tailX = width - roi_width - minX #print minX, minY #print maxX, maxY #print roi_width, roi_height size = roi_width * roi_height n_bytes_per_pixel = pixelType().getBitsPerPixel() / 8 #print n_bytes_per_pixel bytes = zeros(size * n_bytes_per_pixel, 'b') # Read only the 2D ROI ra.seek(header + (minY * width + minX) * n_bytes_per_pixel) for h in xrange(roi_height): ra.readFully(bytes, h * roi_width * n_bytes_per_pixel, roi_width * n_bytes_per_pixel) ra.skipBytes((tailX + minX) * n_bytes_per_pixel) # Make an image roiDims = [roi_width, roi_height] if UnsignedByteType == pixelType: return ArrayImgs.unsignedBytes(bytes, roiDims) if UnsignedShortType == pixelType: shorts = zeros(size, 'h') ByteBuffer.wrap(bytes).order(byte_order).asShortBuffer().get(shorts) return ArrayImgs.shorts(shorts, roiDims) if FloatType == pixelType: floats = zeros(size, 'f') ByteBuffer.wrap(bytes).order(byte_order).asFloatBuffer().get(floats) return ArrayImgs.floats(floats, roiDims) finally: ra.close()
def populateInstances(instances, synth_imgs, class_index, mins, maxs): # Populate the training data: create the filter bank for each feature image # by reading values from the interval defined by mins and maxs target = ArrayImgs.floats([width, height]) interval = FinalInterval(mins, maxs) n_samples = Intervals.numElements(interval) for img in synth_imgs: vectors = [zeros(len(attributes), 'd') for _ in xrange(n_samples)] for k, op in enumerate(filterBank(img, sumType=DoubleType())): imgOp = compute(op).into(target) for i, v in enumerate(Views.interval(imgOp, interval)): vectors[i][k] = v.getRealDouble() for vector in vectors: vector[-1] = class_index instances.add(DenseInstance(1.0, vector))
def readFloats(path, dimensions, header=0, byte_order=ByteOrder.LITTLE_ENDIAN): """ Read a file as an ArrayImg of FloatType """ size = reduce(operator.mul, dimensions) ra = RandomAccessFile(path, 'r') try: if header < 0: # Interpret from the end: useful for files with variable header lengths # such as some types of uncompressed TIFF formats header = ra.length() + header ra.skipBytes(header) bytes = zeros(size * 4, 'b') ra.read(bytes) floats = zeros(size, 'f') ByteBuffer.wrap(bytes).order(byte_order).asFloatBuffer().get(floats) return ArrayImgs.floats(floats, dimensions) finally: ra.close()
def twoStep(index=0): # The current way: img = klb.readFull(filepaths[index]) # klb_loader.get(filepaths[index]) imgE = Views.extendZero(img) imgI = Views.interpolate(imgE, NLinearInterpolatorFactory()) imgT = RealViews.transform(imgI, cmIsotropicTransforms[index]) imgB = Views.zeroMin(Views.interval(imgT, roi[0], roi[1])) # bounded: crop with ROI imgBA = ArrayImgs.unsignedShorts(Intervals.dimensionsAsLongArray(imgB)) ImgUtil.copy(ImgView.wrap(imgB, imgBA.factory()), imgBA) imgP = prepareImgForDeconvolution( imgBA, affine3D(fineTransformsPostROICrop[index]).inverse(), FinalInterval([0, 0, 0], [imgB.dimension(d) - 1 for d in xrange(3)])) # Copy transformed view into ArrayImg for best performance in deconvolution imgA = ArrayImgs.floats(Intervals.dimensionsAsLongArray(imgP)) ImgUtil.copy(ImgView.wrap(imgP, imgA.factory()), imgA) IL.wrap(imgA, "two step").show()
def prepare(index): # Prepare the img for deconvolution: # 0. Transform in one step. # 1. Ensure its pixel values conform to expectations (no zeros inside) # 2. Copy it into an ArrayImg for faster recurrent retrieval of same pixels syncPrint("Preparing %s CM0%i for deconvolution" % (tm_dirname, index)) img = klb_loader.get(filepaths[index]) # of UnsignedShortType imgP = prepareImgForDeconvolution( img, transforms[index], target_interval) # returns of FloatType # Copy transformed view into ArrayImg for best performance in deconvolution imgA = ArrayImgs.floats(Intervals.dimensionsAsLongArray(imgP)) #ImgUtil.copy(ImgView.wrap(imgP, imgA.factory()), imgA) ImgUtil.copy(imgP, imgA, n_threads / 2) # parallel copying syncPrint("--Completed preparing %s CM0%i for deconvolution" % (tm_dirname, index)) imgP = None img = None return (index, imgA)
def oneStep(index=0): # Combining transforms into one, via a translation to account of the ROI crop img = klb.readFull(filepaths[index]) # klb_loader.get(filepaths[index]) t1 = cmIsotropicTransforms[index] t2 = affine3D( [1, 0, 0, -roi[0][0], 0, 1, 0, -roi[0][1], 0, 0, 1, -roi[0][2]]) t3 = affine3D(fineTransformsPostROICrop[index]).inverse() aff = AffineTransform3D() aff.set(t1) aff.preConcatenate(t2) aff.preConcatenate(t3) # Final interval is now rooted at 0,0,0 given that the transform includes the translation imgP = prepareImgForDeconvolution( img, aff, FinalInterval([0, 0, 0], [maxC - minC for minC, maxC in izip(roi[0], roi[1])])) # Copy transformed view into ArrayImg for best performance in deconvolution imgA = ArrayImgs.floats(Intervals.dimensionsAsLongArray(imgP)) ImgUtil.copy(ImgView.wrap(imgP, imgA.factory()), imgA) IL.wrap(imgA, "one step index %i" % index).show()
def createTrainingData(img, samples, class_names, n_samples=0, ops=None): """ img: a 2D RandomAccessibleInterval. samples: a sequence of long[] (or int numeric sequence or Localizable) and class_index pairs; can be a generator. n_samples: optional, the number of samples (in case samples is e.g. a generator). class_names: a list of class names, as many as different class_index. ops: optional, the sequence of ImgMath ops to apply to the img, defaults to filterBank(img) return an instance of WEKA Instances """ ops = ops if ops else filterBank(img) if 0 == n_samples: n_samples = len(samples) # Define a WEKA Attribute for each feature (one for op in the filter bank, plus the class) attribute_names = ["attr-%i" % (i+1) for i in xrange(len(ops))] attributes = ArrayList() for name in attribute_names: attributes.add(Attribute(name)) # Add an attribute at the end for the classification classes attributes.add(Attribute("class", class_names)) # Create the training data structure training_data = Instances("training", attributes, n_samples) training_data.setClassIndex(len(attributes) -1) opImgs = [compute(op).into(ArrayImgs.floats([img.dimension(0), img.dimension(1)])) for op in ops] ra = Views.collapse(Views.stack(opImgs)).randomAccess() for position, class_index in samples: ra.setPosition(position) tc = ra.get() vector = array((tc.get(i).getRealDouble() for i in xrange(len(opImgs))), 'd') vector += array([class_index], 'd') training_data.add(DenseInstance(1.0, vector)) return training_data
from net.imglib2.type.numeric.real import FloatType ft = FloatType(10) ft.pow(2) print ft from net.imglib2.algorithm.math.ImgMath import compute, add, power from net.imglib2.img.array import ArrayImgs from net.imglib2.img.display.imagej import ImageJFunctions as IL img = ArrayImgs.floats([10, 10, 10]) compute(add(img, 5)).into(img) # in place compute(power(img, 2)).into(img) # in place print 25 * 10 * 10 * 10 == sum(t.get() for t in img.cursor()) IL.wrap(img, "5 squared").show()
from net.imglib2.algorithm.math import ImgMath from net.imglib2.util import ImgUtil from net.imglib2.img import ImgView import sys sys.path.append("/home/albert/lab/scripts/python/imagej/IsoView-GCaMP/") from lib.util import timeit roi = ( [1, 228, 0], # top-left coordinates [1 + 406 - 1, 228 + 465 - 1, 0 + 325 - 1]) # bottom-right coordinates (inclusive, hence the -1) dimensions = [maxC - minC + 1 for minC, maxC in zip(roi[0], roi[1])] imgU = ArrayImgs.unsignedShorts(dimensions) imgF = ArrayImgs.floats(dimensions) #c = imgF.cursor() #while c.hasNext(): # c.next().set(random() * 65535) ImgMath.compute(ImgMath.number(17)).into(imgF) ImgMath.compute(ImgMath.img(imgF)).into(imgU) aff = AffineTransform3D() """ aff.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0) """ aff.set(*[ 0.9999949529841275, -0.0031770224721305684, 2.3118912942710207e-05, -1.6032353998500826, 0.003177032139125933, 0.999994860398559, -0.00043086338151948394, -0.4401520585103873, -2.1749931475206362e-05,
for i, v in enumerate(Views.interval(imgOp, interval)): vectors[i][k] = v.getRealDouble() for vector in vectors: vector[-1] = class_index instances.add(DenseInstance(1.0, vector)) # pick pixels on the black line for class 0 (membrane), 4x4 populateInstances(training_data, synth_imgs_membrane, 0, [14, 14], [17, 17]) # pick pixels in the very center for class 1 (mitochondrial boundary), 2x2 populateInstances(training_data, synth_imgs_mit_boundary, 1, [15, 15], [16, 16]) # Populate the training data for class "other" from two images # entirely filled with background or foreground plus noise target = ArrayImgs.floats([width, height]) interval = FinalInterval([14, 14], [17, 17]) n_samples = Intervals.numElements(interval) for ci, v in enumerate([fillValue, backgroundValue]): for _ in xrange(training_data.size() / 4): # the other 2/4 are the membrane and mit boundary other = syntheticEM([], width, height, 0, v, noise=True) vectors = [zeros(len(attributes), 'd') for _ in xrange(n_samples)] for k, op in enumerate(filterBank(IL.wrap(other), sumType=DoubleType())): imgOp = compute(op).into(target) for i, v in enumerate(Views.interval(imgOp, interval)): vectors[i][k] = v.getRealDouble() for vector in vectors: vector[-1] = ci + 2 # class index training_data.add(DenseInstance(1.0, vector))
# @OpService ops # @float[] arr # @long[] dims # @OUTPUT Img out from net.imagej.ops import Ops from net.imglib2.img import Img from net.imglib2.img.array import ArrayImgs arr = list(arr) dims = list(dims) out = ArrayImgs.floats(arr, dims)
def __init__(self, dimensions, filenames): super(Thread, self).__init__() self.filenames = filenames self.aimg = ArrayImgs.floats(dimensions) self.klb = KLB.newInstance()
def factory(self): return None def copy(self): return self # stateless, so safe def randomAccess( self, interval=None ): # optional argument handles case of having randomAccess() and randomAccess(interval). return self.cursor() def cursor(self): return FnCursor(self.numDimensions(), -pi / 2, self.dimension(0) / 4) def localizingCursor(self): return self.cursor() img = FnImg([512, 512]) IL.show(img) # shows black, yet above the get() prints values aimg = ArrayImgs.floats([512, 512]) c1 = img.cursor() c2 = aimg.cursor() while c2.hasNext(): t = c2.next() c1.setPosition(c2) c2.next().set(c1.get()) IL.show(aimg) # Shows black, yet above the get() prints values
imgB0, transformedView(imgB1, matrices["imgB0-imgB1"]), transformedView(imgB2, matrices["imgB0-imgB2"]), transformedView(imgB3, matrices["imgB0-imgB3"]) ] #viewInBDV(*transformed) viewAsStack(*transformed) exe = newFixedThreadPool(4) try: # Copy into ArrayImg def copyIntoArrayImg(img): return ImgMath.compute(ImgMath.img(img)).into(ArrayImgs.floats([img.dimension(d) for d in xrange(img.numDimensions())])) futures = [exe.submit(Task(copyIntoArrayImg, img)) for img in [imgB0, imgB1, imgB2, imgB3]] imgB0, imgB1, imgB2, imgB3 = [f.get() for f in futures] finally: exe.shutdown() viewAsStack(imgB0, imgB1, imgB2, imgB3) # ArrayImg instances # Read the kernel as a FloatType ArrayImg kernel = readFloats("/home/albert/lab/Raghav-IsoView-PSF/PSF-19x19x25.tif", [19, 19, 25], header=434) def affine3D(matrix): aff = AffineTransform3D() aff.set(*matrix) return aff
def readKernel(path): if kernel_header is None: imp = IJ.openImage(path) return ArrayImgs.floats(imp.getProcessor().getPixels(), [imp.getWidth(), imp.getHeight(), imp.getNSlices()]) return readFloats(path, kernel_dimensions, kernel_header)
def testASMFloats(): img2 = ArrayImgs.floats(dimensions) ImgUtil.copy( ImgView.wrap( Converters.convertRandomAccessibleIterableInterval( img1, sampler_conv_floats), img1.factory()), img2)
from net.imglib2.img.array import ArrayImgs import sys sys.path.append("/home/albert/lab/scripts/python/imagej/IsoView-GCaMP/") from random import random from net.imglib2.loops import LoopBuilder from net.imglib2.type.numeric.real import FloatType from lib.loop import createBiConsumerTypeSet, createBiConsumerTypeSet2, binaryLambda, nthLambda from java.util.function import BiConsumer img1 = ArrayImgs.floats([10, 10, 10]) cursor = img1.cursor() for t in img1: t.setReal(random()) img2 = ArrayImgs.floats([10, 10, 10]) #copyIt = createBiConsumerTypeSet(FloatType) # works well #copyIt = createBiConsumerTypeSet2(FloatType) # works well #LoopBuilder.setImages(img1, img2).forEachPixel(copyIt) # Works well: #copyIt = binaryLambda(FloatType, "set", FloatType, # interface=BiConsumer, interface_method="accept") copyIt = nthLambda(FloatType, "set", [FloatType], BiConsumer, "accept") ra1 = img1.randomAccess() ra2 = img2.randomAccess() pos = [3, 2, 5] ra1.setPosition(pos)
def test(red, green, blue, easy=True): saturation = let( "red", red, "green", green, "blue", blue, "max", maximum("red", "green", "blue"), "min", minimum("red", "green", "blue"), IF(EQ(0, "max"), THEN(0), ELSE(div(sub("max", "min"), "max")))) brightness = div(maximum(red, green, blue), 255.0) hue = IF( EQ(0, saturation), THEN(0), ELSE( let( "red", red, "green", green, "blue", blue, "max", maximum("red", "green", "blue"), "min", minimum("red", "green", "blue"), "range", sub("max", "min"), "redc", div(sub("max", "red"), "range"), "greenc", div(sub("max", "green"), "range"), "bluec", div(sub("max", "blue"), "range"), "hue", div( IF( EQ("red", "max"), THEN(sub("bluec", "greenc")), ELSE( IF(EQ("green", "max"), THEN(sub(add(2, "redc"), "bluec")), ELSE(sub(add(4, "greenc"), "redc"))))), 6), IF(LT("hue", 0), THEN(add("hue", 1)), ELSE("hue"))))) #print hierarchy(hue) #print "hue view:", hue.view( FloatType() ).iterationOrder() if easy: # About 26 ms """ hsb = Views.stack( hue.view( FloatType() ), saturation.view( FloatType() ), brightness.view( FloatType() ) ) """ # About 13 ms: half! Still much worse than plain ImageJ, # but the source images are iterated 4 times, rather than just once, # and the saturation is computed twice, # and the min, max is computed 3 and 4 times, respectively. hsb = Views.stack(hue.viewDouble(FloatType()), saturation.viewDouble(FloatType()), brightness.viewDouble(FloatType())) """ # Even worse: ~37 ms width, height = rgb.dimension(0), rgb.dimension(1) h = compute(hue).into(ArrayImgs.floats([width, height])) s = compute(saturation).into(ArrayImgs.floats([width, height])) b = compute(brightness).into(ArrayImgs.floats([width, height])) hsb = Views.stack( h, s, b ) """ imp = IL.wrap(hsb, "HSB view") else: # Tested it: takes more time (~40 ms vs 26 ms above) width, height = rgb.dimension(0), rgb.dimension(1) hb = zeros(width * height, 'f') sb = zeros(width * height, 'f') bb = zeros(width * height, 'f') h = ArrayImgs.floats(hb, [width, height]) s = ArrayImgs.floats(sb, [width, height]) b = ArrayImgs.floats(bb, [width, height]) #print "ArrayImg:", b.iterationOrder() ImgUtil.copy(ImgView.wrap(hue.view(FloatType()), None), h) ImgUtil.copy(ImgView.wrap(saturation.view(FloatType()), None), s) ImgUtil.copy(ImgView.wrap(brightness.view(FloatType()), None), b) stack = ImageStack(width, height) stack.addSlice(FloatProcessor(width, height, hb, None)) stack.addSlice(FloatProcessor(width, height, sb, None)) stack.addSlice(FloatProcessor(width, height, bb, None)) imp = ImagePlus("hsb", stack) return imp
imp = IJ.getImage() dimensions = [imp.getWidth(), imp.getHeight()] ip = imp.getProcessor() pixels = ip.getPixels() # In practice, you never want to do this below, # and instead you'd use the built-in wrapper: ImageJFunctions.wrap(imp) # This is merely for illustration of how to use ArrayImgs with an existing pixel array if isinstance(ip, ByteProcessor): img1 = ArrayImgs.unsignedBytes(pixels, dimensions) elif isinstance(ip, ShortProcessor): img1 = ArrayImgs.unsignedShorts(pixels, dimensions) elif isinstance(ip, FloatProcessor): img1 = ArrayImgs.floats(pixels, dimensions) else: print "Can't handle image of type:", type(ip).getName() # An empty image of float[] img2 = ArrayImgs.floats(dimensions) # View it as RandomAccessibleInterval<FloatType> by converting on the fly # using a generic RealType to FloatType converter floatView = Converters.convertRAI(img1, RealFloatConverter(), FloatType()) # The above 'floatView' can be used as an image: one that gets always converted on demand. # If you only have to iterate over the pixels just once, there's no need to create a new image. IL.show(floatView, "32-bit view of the 8-bit")
imgE = Views.extendZero(target) # Integrate every dimension, cummulatively by writing into # a target image that is also the input for d in xrange(img.numDimensions()): coord = [0] * img.numDimensions() # array of zeros coord[d] = -1 # Cummulative sum along the current dimension # Note that instead of the ImgMath offset op, # we could have used Views.translate(Views.extendZero(target), [1, 0])) # (Notice though the sign change in the translation) integral = add(target, offset(imgE, coord)) compute(integral).into(target) # The target is the integral image integralImg = target # Read out blocks of radius 5 (i.e. 10x10 for a 2d image) # in a way that is entirely n-dimensional (applies to 1d, 2d, 3d, 4d ...) radius = 5 nd = img.numDimensions() op = div(block(Views.extendBorder(integralImg), [radius] * nd), pow(radius * 2, nd)) # divide by total number of pixels in the block blurred = ArrayImgs.floats(Intervals.dimensionsAsLongArray(img)) compute(op).into(blurred, FloatType()) # Show the blurred image with the same LUT as the original imp2 = IL.wrap(blurred, "integral image radius 5 blur") imp2.getProcessor().setLut(imp.getProcessor().getLut()) imp2.show()