def rotatedView(img, angle, enlarge=True, extend=Views.extendBorder): """ Return a rotated view of the image, around the Z axis, with an expanded (or reduced) interval view so that all pixels are exactly included. img: a RandomAccessibleInterval angle: in degrees """ cx = img.dimension(0) / 2.0 cy = img.dimension(1) / 2.0 toCenter = AffineTransform2D() toCenter.translate(-cx, -cy) rotation = AffineTransform2D() # Step 1: place origin of rotation at the center of the image rotation.preConcatenate(toCenter) # Step 2: rotate around the Z axis rotation.rotate(radians(angle)) # Step 3: undo translation to the center rotation.preConcatenate(toCenter.inverse()) rotated = RV.transform(Views.interpolate(extend(img), NLinearInterpolatorFactory()), rotation) if enlarge: # Bounds: bounds = repeat((sys.maxint, 0)) # initial upper- and lower-bound values # for min, max to compare against transformed = zeros(2, 'f') for corner in product(*zip(repeat(0), Intervals.maxAsLongArray(img))): rotation.apply(corner, transformed) bounds = [(min(vmin, int(floor(v))), max(vmax, int(ceil(v)))) for (vmin, vmax), v in zip(bounds, transformed)] minC, maxC = map(list, zip(*bounds)) # transpose list of 2 pairs # into 2 lists of 2 values imgRot = Views.zeroMin(Views.interval(rotated, minC, maxC)) else: imgRot = Views.interval(rotated, img) return imgRot
def asNormalizedUnsignedByteArrayImg(interval, invert, blockRadius, n_bins, slope, matrices, copy_threads, index, imp): sp = imp.getProcessor() # ShortProcessor sp.setRoi(interval.min(0), interval.min(1), interval.max(0) - interval.min(0) + 1, interval.max(1) - interval.min(1) + 1) sp = sp.crop() if invert: sp.invert() CLAHE.run( ImagePlus("", sp), blockRadius, n_bins, slope, None ) # far less memory requirements than NormalizeLocalContrast, and faster. minimum, maximum = autoAdjust(sp) # Transform and convert image to 8-bit, mapping to display range img = ArrayImgs.unsignedShorts( sp.getPixels(), [sp.getWidth(), sp.getHeight()]) sp = None affine = AffineTransform2D() affine.set(matrices[index]) imgI = Views.interpolate(Views.extendZero(img), NLinearInterpolatorFactory()) imgA = RealViews.transform(imgI, affine) imgT = Views.zeroMin(Views.interval(imgA, img)) imgMinMax = convert(imgT, RealUnsignedByteConverter(minimum, maximum), UnsignedByteType) aimg = ArrayImgs.unsignedBytes(Intervals.dimensionsAsLongArray(img)) ImgUtil.copy(ImgView.wrap(imgMinMax, aimg.factory()), aimg, copy_threads) img = imgI = imgA = imgT = imgMinMax = None return aimg
def makeCell(self, index): self.preloadCells(index) # preload others in the background img = self.loadImg(self.filepaths[index]) affine = AffineTransform2D() affine.set(self.matrices[index]) imgI = Views.interpolate(Views.extendZero(img), NLinearInterpolatorFactory()) imgA = RealViews.transform(imgI, affine) imgT = Views.zeroMin(Views.interval(imgA, self.interval)) aimg = img.factory().create(self.interval) ImgUtil.copy(ImgView.wrap(imgT, aimg.factory()), aimg) return Cell(self.cell_dimensions, [0, 0, index], aimg.update(None))
def asNormalizedUnsignedByteArrayImg(interval, invert, blockRadius, n_bins, slope, matrices, index, imp): sp = imp.getProcessor() # ShortProcessor # Crop to interval if needed x = interval.min(0) y = interval.min(1) width = interval.max(0) - interval.min(0) + 1 height = interval.max(1) - interval.min(1) + 1 if 0 != x or 0 != y or sp.getWidth() != width or sp.getHeight( ) != height: sp.setRoi(x, y, width, height) sp = sp.crop() if invert: sp.invert() CLAHE.run( ImagePlus("", sp), blockRadius, n_bins, slope, None ) # far less memory requirements than NormalizeLocalContrast, and faster. minimum, maximum = autoAdjust(sp) # Transform and convert image to 8-bit, mapping to display range img = ArrayImgs.unsignedShorts( sp.getPixels(), [sp.getWidth(), sp.getHeight()]) sp = None imp = None # Must use linear interpolation for subpixel precision affine = AffineTransform2D() affine.set(matrices[index]) imgI = Views.interpolate(Views.extendZero(img), NLinearInterpolatorFactory()) imgA = RealViews.transform(imgI, affine) imgT = Views.zeroMin(Views.interval(imgA, img)) # Convert to 8-bit imgMinMax = convert2(imgT, RealUnsignedByteConverter(minimum, maximum), UnsignedByteType, randomAccessible=False) # use IterableInterval aimg = ArrayImgs.unsignedBytes(Intervals.dimensionsAsLongArray(img)) # ImgUtil copies multi-threaded, which is not appropriate here as there are many other images being copied too #ImgUtil.copy(ImgView.wrap(imgMinMax, aimg.factory()), aimg) # Single-threaded copy copier = createBiConsumerTypeSet(UnsignedByteType) LoopBuilder.setImages(imgMinMax, aimg).forEachPixel(copier) img = imgI = imgA = imgMinMax = imgT = None return aimg
# push image to GPU input = clij.push(imp); shiftXgpu = clij.push(shiftX); rotatedShiftXgpu = clij.create(shiftXgpu); shiftYgpu = clij.push(shiftY); temp = clij.create(input); # reserve memory for output output = clij.create([input.getWidth(), input.getHeight(), 36], input.getNativeType()); for i in range(0, 36): # change the shift from slice to slice at = AffineTransform2D(); at.translate(-input.getWidth() / 2, -input.getHeight() / 2); at.rotate(i * 10.0 / 180.0 * Math.PI); at.translate(input.getWidth() / 2, input.getHeight() / 2); clij.op().affineTransform2D(shiftXgpu, rotatedShiftXgpu, at); # apply transform clij.op().applyVectorfield(input, rotatedShiftXgpu, shiftYgpu, temp); # put resulting 2D image in the right plane clij.op().copySlice(temp, output, i); # show result clij.pull(output).show();
# advantage of then letting us apply a single transform to the image, # reducing not only the number of operations per pixel (and therefore gaining # in speed performance) but also reducing the noise, by avoiding the repeated # transformation (with its floating-point error from interpolations) of the image. # # # Handling angles by using sin and cos, though, is fidgety and error-prone. # Instead, let's develop an intuitive understanding first, # and then show how to use existing convenience methods so that # we never have to use sin and cos in our own code. # Flip horizontally: # Multiply the X axis coordinates by -1, # and translate X axis coordinates by the image width # so as to bring the data back into the interval [0, width] mirrorX = AffineTransform2D() mirrorX.set(-1.0, 0.0, imp.getWidth(), 0.0, 1.0, 0.0) viewTransformed(imp, mirrorX, title=imp.getTitle() + " mirrorX") # Flip vertically: # Multiply the Y axis coordinates by -1, # and translate the Y axis coordinates by the image height # so as to bring the data back into the interval [0, height] mirrorY = AffineTransform2D() mirrorY.set(1.0, 0.0, 0.0, 0.0, -1.0, imp.getHeight()) viewTransformed(imp, mirrorY, title=imp.getTitle() + " mirrorY") # Flip simultaneously horizontally and vertically mirrorXY = AffineTransform2D()
interval = interval_start + interval_end interval = Intervals.createMinMax(*interval) output = ops.run("transform.crop", data, interval, True) return output # Get the center of the images so we do the rotation according to it center = [int(round((data.max(d) / 2 + 1))) for d in range(2)] # Convert angles to radians angle_rad = angle * math.pi / 180 # Build the affine transformation affine = AffineTransform2D() affine.translate([-p for p in center]) affine.rotate(angle_rad) affine.translate(center) # Get the interpolator interpolator = LanczosInterpolatorFactory() # Iterate over all frame in the stack axis = Axes.TIME output = [] for d in range(data.dimension(axis)): # Get the current frame frame = crop_along_one_axis(ops, data, [d, d], "TIME")
# Third approach: pull (CORRECT!), and much faster (delegates pixel-wise operations # to java libraries) # Defines a list of views (recipes, really) for transforming every stack slice # and then materializes the view by copying it in a multi-threaded way into an ArrayImg. from net.imglib2 import FinalInterval from net.imglib2.converter import Converters, ColorChannelOrder from net.imglib2.view import Views from net.imglib2.img.display.imagej import ImageJFunctions as IL from net.imglib2.realtransform import RealViews, AffineTransform2D from net.imglib2.img.array import ArrayImgs from net.imglib2.util import Intervals, ImgUtil from net.imglib2.interpolation.randomaccess import NLinearInterpolatorFactory img1 = Views.dropSingletonDimensions(IL.wrap(imp)) transform = AffineTransform2D() transform.set(scale, 0, 0, 0, scale, 0) # Origins and dimensions (hence, interval) of the target image interval2 = FinalInterval([ int(img1.dimension(0) * scale), int(img1.dimension(1) * scale), img1.dimension(2) ]) # Interval of a single stack slice of the target image sliceInterval = FinalInterval([interval2.dimension(0), interval2.dimension(1)]) slices2 = [] for index in xrange(img1.dimension(2)): # One single 2D RGB slice imgSlice1 = Views.hyperSlice(img1, 2, index)