Exemplo n.º 1
0
def findPeaks(img4D, params):
  """
  img4D: a 4D RandomAccessibleInterval
  params["frames"]: the number of consecutive time points to average
                    towards detecting peaks with difference of Gaussian.

  Returns a list of lists of peaks found, one list per time point.
  """
  frames = params["frames"]
  # Work image: the current sum
  sum3D = ArrayImgs.unsignedLongs([img4D.dimension(d) for d in [0, 1, 2]])

  peaks = []

  # Sum of the first set of frames
  compute(add([Views.hyperSlice(img4D, 3, i) for i in xrange(frames)])).into(sum3D)
  # Extract nuclei from first sum3D
  peaks.append(doGPeaks(sum3D, params))

  # Running sums: subtract the first and add the last
  for i in xrange(frames, img4D.dimension(3), 1):
    compute(add(sub(sum3D,
                    Views.hyperSlice(img4D, 3, i - frames)),
                Views.hyperSlice(img4D, 3, i))) \
      .into(sum3D)
    # Extract nuclei from sum4D
    peaks.append(doGPeaks(sum3D, params))

  return peaks
 def getPixels(self, n):
     # 'n' is 1-based
     aimg = ArrayImgs.unsignedShorts(self.dimensions[0:2])
     #computeInto(ImgSource(Views.hyperSlice(self.img4d, 2, n-1)), aimg)
     nZ = self.img4d.dimension(2)
     fixedT = Views.hyperSlice(self.img4d, 3, int((n - 1) / nZ))  # Z blocks
     fixedZ = Views.hyperSlice(fixedT, 2, (n - 1) % nZ)
     w.copy(fixedZ.cursor(), aimg.cursor())
     return aimg.update(None).getCurrentStorageArray()
def looping(img, center):
  for z in xrange(img.dimension(2)):
    radius = img.dimension(0) * 0.5 / (z + 1)
    circle = GeomMasks.openSphere(center, radius)
    # Works, explicit iteration of every pixel
    for t in Regions.sample(circle, Views.hyperSlice(img, 2, z)):
      t.setOne()
Exemplo n.º 4
0
def findNucleiOverTime(img4D, params, show=True):
    """
  params["frames"]: number of time frames to average
  params["calibration"]: e.g. [1.0, 1.0, 1.0]
  params["somaDiameter"]: width of a soma, in pixels
  params["minPeakValue"]: determine it by hand with e.g. difference of Gaussians sigma=somaDiameter/4 minus sigma=somaDiameter/2
  params["sigmaSmaller"]: for difference of Gaussian to detect somas. Recommended somaDiameter / 4.0 -- in pixels
  params["sigmaLarger"]: for difference of Gaussian to detect somas. Recommended somaDiameter / 2.0 -- in pixels
  params["searchRadius"]: for finding nearby DoG peaks which are actually the same soma. Recommended somaDiameter / 3.0 -- in pixels
  parmams["min_count"]: to consider only somas detected in at least min_count time points, i.e. their coordinates are the average
                        of at least min_count independent detections.
  """
    peaks = findPeaks(img4D, params)
    mergedPeaks = mergePeaks(peaks, params)
    nuclei = filterNuclei(mergedPeaks, params)

    # Show as a 3D volume with spheres
    if show:
        spheresRAI = virtualPointsRAI(nuclei, params["somaDiameter"] / 2.0,
                                      Views.hyperSlice(img4D, 3, 1))
        imp = showStack(spheresRAI,
                        title="nuclei (min_count=%i)" % params["min_count"])
        return peaks, mergedPeaks, nuclei, spheresRAI, imp

    return peaks, mergedPeaks, nuclei
Exemplo n.º 5
0
def dropSlices(img, nth):
  """
  Drop every nth slice.
  The calibration is then to be multipled by nth for Z.
  Counts slices 1-based so as to preserve the first slice (index zero).
  """
  return Views.stack([Views.hyperSlice(img, 2, i) for i in xrange(img.dimension(2)) if 0 == (i+1) % nth])
Exemplo n.º 6
0
def MakeMultiChannelPhantom(ops, size):

    if len(size) > 3:
        numChannels = size[3]
    else:
        numChannels = 1

    image = ops.run("create", size, FloatType())
    ax = [Axes.X, Axes.Y, Axes.Z, Axes.CHANNEL]
    imgPlus = ImgPlus(image, "phantom", ax)

    location = zeros(3, 'i')
    location[0] = 40
    location[1] = size[1] / 2
    location[2] = size[2] / 2

    #ops.run("addsphere",  image, location, radius, 1.0)
    #ops.run("addassymetricspherel",  image, location, 1.0, radius1, radius2)

    shapes = Add3DShapes(ops, size)

    def AddShapes(hyperSlice):
        #shapes.addRandomPointsInROI(hyperSlice, 100.0, 20)
        shapes.addCenterSphere(hyperSlice, 5.0, 20)

    if (numChannels > 1):
        for d in range(0, numChannels):
            hyperSlice = Views.hyperSlice(image, 3, d)
            AddShapes(hyperSlice)
            location[0] += 10
    else:
        AddShapes(image)

    return imgPlus
def MakeMultiChannelPhantom (ops, size):

	if len(size)>3:
		numChannels=size[3]
	else:
		numChannels=1

	image=ops.run("create", size,  FloatType())
	ax=[Axes.X, Axes.Y, Axes.Z, Axes.CHANNEL]
	imgPlus=ImgPlus(image, "phantom", ax)
	
	location=zeros(3,'i')
	location[0]=40;
	location[1]=size[1]/2;
	location[2]=size[2]/2;
	
	#ops.run("addsphere",  image, location, radius, 1.0)
	#ops.run("addassymetricspherel",  image, location, 1.0, radius1, radius2)

 	shapes=Add3DShapes(ops, size)

 	def AddShapes(hyperSlice):
 		#shapes.addRandomPointsInROI(hyperSlice, 100.0, 20)
		shapes.addCenterSphere(hyperSlice, 5.0, 20)

	if (numChannels>1):
		for d in range(0,numChannels):
			hyperSlice= Views.hyperSlice(image, 3, d)
			AddShapes(hyperSlice)
			location[0]+=10
	else:
		AddShapes(image)

	return imgPlus
def getDoGPeaks(timepoint_index, calibration):
    img = Views.hyperSlice(vol4d, 3, timepoint_index)
    dog = createDoG(img, calibration, sigmaSmaller, sigmaLarger, minPeakValue)
    peaks = dog.getSubpixelPeaks(
    )  # could also use getPeaks() in integer precision
    # Return peaks in calibrated units
    for peak in peaks:
        for d, cal in enumerate(calibration):
            peak.setPosition(peak.getFloatPosition(d) * cal, d)
    return peaks
Exemplo n.º 9
0
 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 getPixels(self, n):
     # 'n' is 1-based
     # Target 2D array img to copy data into
     aimg = ArrayImgs.unsignedShorts(self.dimensions[0:2])
     # The number of slices of the 3D volume of a single timepoint
     nZ = self.img4d.dimension(2)
     # The slice_index if there was a single channel
     slice_index = int((n - 1) / 2)  # 0-based, of the whole 4D series
     local_slice_index = slice_index % nZ  # 0-based, of the timepoint 3D volume
     timepoint_index = int(slice_index / nZ)  # Z blocks
     if 1 == n % 2:
         # Odd slice index: image channel
         fixedT = Views.hyperSlice(self.img4d, 3, timepoint_index)
         fixedZ = Views.hyperSlice(fixedT, 2, local_slice_index)
         w.copy(fixedZ.cursor(), aimg.cursor())
     else:
         # Even slice index: spheres channel
         sd = SpheresData(self.kdtrees[timepoint_index], radius, inside,
                          outside)
         volume = Views.interval(Views.raster(sd), self.dimensions3d)
         plane = Views.hyperSlice(volume, 2, local_slice_index)
         w.copy(plane.cursor(), aimg.cursor())
     #
     return aimg.update(None).getCurrentStorageArray()
Exemplo n.º 11
0
def projectLastDimension(img, showEarly=False):
    """
  Project the last dimension, e.g. a 4D image becomes a 3D image,
  using the provided reducing function (e.g. min, max, sum).
  """
    last_dimension = img.numDimensions() - 1
    # The collapsed image
    imgC = ArrayImgs.unsignedShorts(
        [img.dimension(d) for d in xrange(last_dimension)])

    if showEarly:
        showStack(
            imgC,
            title="projected")  # show it early, will be updated progressively

    if img.dimension(last_dimension) > 10:
        # one by one
        print "One by one"
        for i in xrange(img.dimension(last_dimension)):
            print i
            compute(maximum(imgC, Views.hyperSlice(img, last_dimension,
                                                   i))).into(imgC)
    else:
        # Each sample of img3DV is a virtual vector over all time frames at that 3D coordinate:
        imgV = Views.collapseReal(img)
        # Reduce each vector to a single scalar, using a Converter
        # The Converter class
        reduce_max = makeCompositeToRealConverter(
            reducer_class=Math,
            reducer_method="max",
            reducer_method_signature="(DD)D")
        img3DC = convert(imgV, reduce_max.newInstance(),
                         img.randomAccess().get().getClass())
        ImgUtil.copy(ImgView.wrap(imgV, img.factory()), imgC)

    return imgC
Exemplo n.º 12
0
  "maxEpsilon": somaDiameter * 0.1, # max allowed alignment error in calibrated units (a distance)
  "minInlierRatio": 0.0000001, # ratio inliers/candidates
  "minNumInliers": 5, # minimum number of good matches to accept the result
  "n_iterations": 2000, # for estimating the model
  "maxTrust": 4, # for rejecting candidates
}

# Joint dictionary of parameters
params = {}
params.update(paramsDoG)
params.update(paramsFeatures)
params.update(paramsModel)

calibration = [1.0, 1.0, 1.0]

img1 = Views.hyperSlice(unregistered, 3, 0)
img2 = Views.hyperSlice(unregistered, 3, 1)

peaks1 = getDoGPeaks(img1, calibration, params["sigmaSmaller"], params["sigmaLarger"], params['minPeakValue'])
peaks2 = getDoGPeaks(img2, calibration, params["sigmaSmaller"], params["sigmaLarger"], params['minPeakValue'])

print "DoG peaks1: %i" % len(peaks1)
print "DoG peaks2: %i" % len(peaks2)

features1 = ConstellationPlus.extractFeatures(peaks1,
                                              makeRadiusSearch(peaks1),
                                              params['radius'],
                                              params['max_per_peak'],
                                              params['min_neighbors'],
                                              params['max_neighbors'])
Exemplo n.º 13
0
from net.imglib2.converter import Converters, ColorChannelOrder
from net.imglib2.img.display.imagej import ImageJFunctions as IL
from net.imglib2.view import Views
from ij import IJ, ImagePlus

# Fetch an RGB image stack (or any RGB image with more than 1 dimension)
imp_rgb = IJ.getImage(
)  # IJ.openImage("http://imagej.nih.gov/ij/images/flybrain.zip")

img = IL.wrap(imp_rgb)  # an ARGBType Img
red = Converters.argbChannel(img, 1)  # a view of the ARGB red channel

# Project the last dimension using the max function
last_d = red.numDimensions() - 1
op = maximum(
    [Views.hyperSlice(red, last_d, i) for i in xrange(red.dimension(last_d))])
img_max_red = compute(op).intoArrayImg()

IL.wrap(img_max_red, "max projection of the red channel)").show()

# Now project all 3 color channels and compose an RGB image
last_dim_index = img.numDimensions() - 1
channel_stacks = [[
    Views.hyperSlice(Converters.argbChannel(img, channel_index),
                     last_dim_index, slice_index)
    for slice_index in xrange(img.dimension(last_dim_index))
] for channel_index in [1, 2, 3]]  # 1: red, 2: green, 3: blue

channels = Views.stack([maximum(cs).view() for cs in channel_stacks])
max_rgb = Converters.mergeARGB(channels, ColorChannelOrder.RGB)
Exemplo n.º 14
0
from net.imglib2.img.display.imagej import ImageJFunctions as IL
from net.imglib2.img.array import ArrayImgs
from net.imglib2.roi.geom import GeomMasks
from net.imglib2.roi import Regions
from net.imglib2.view import Views
from net.imglib2.type.logic import BitType
from collections import deque
from itertools import imap

# A binary image
img = ArrayImgs.bits([512, 512, 50])

# Add some data to it
center = img.dimension(0) / 2, img.dimension(1) / 2
for z in xrange(img.dimension(2)):
    radius = img.dimension(0) * 0.5 / (z + 1)
    #print radius
    circle = GeomMasks.openSphere(center, radius)
    # Works, explicit iteration of every pixel
    #for t in Regions.sample(circle, Views.hyperSlice(img, 2, z)):
    #  t.setOne()
    # Works: about twice as fast -- measured with: from time import time .... t0 = time(); ... t1 = time()
    deque(imap(BitType.setOne,
               Regions.sample(circle, Views.hyperSlice(img, 2, z))),
          maxlen=0)

IL.wrap(img, "bit img").show()
Exemplo n.º 15
0
 def hyperSlice(index):
   return Views.hyperSlice(img, last_dimension, index)
# Convert an ARGB image to a stack of 4 channels: a RandomAccessibleInterval<UnsignedByte>
# with one more dimension that before.
# The order of channels in the stack can be changed by changing their indices.
channels = Converters.argbChannels(img, [0, 1, 2, 3])

impChannels = IL.wrap(channels, imp.getTitle() + " channels")
impChannels.show()

# Read out a single channel directly
red = Converters.argbChannel(img, 1)

# Pick a view of the red channel in the channels stack.
# Takes the last dimension, which are the channels,
# and fixes it, pointing to the index of the red channel (1) in the stack.
red = Views.hyperSlice(channels, channels.numDimensions() -1, 1)

impRed = IL.wrap(red, imp.getTitle() + " - red channel")
impRed.show()

# Create an empty image of type FloatType (floating-point values)
# Here, the img is used to read out the interval: the dimensions for the new image
brightness = ArrayImgFactory(FloatType()).create(img)


def iterableChannel(imgARGB, i):
  return Views.iterable(Converters.argbChannel(imgARGB, i))

zipped_channels = izip(iterableChannel(img, 1), # red
                       iterableChannel(img, 2), # green
                       iterableChannel(img, 3), # blue
def dequeing(img, center):
  for z in xrange(img.dimension(2)):
    radius = img.dimension(0) * 0.5 / (z + 1)
    circle = GeomMasks.openSphere(center, radius)
    deque(imap(BitType.setOne, Regions.sample(circle, Views.hyperSlice(img, 2, z))), maxlen=0)
 def load(self, str_index):
   return Views.hyperSlice(unregistered, 3, int(str_index))
def measureFluorescence(series_name, img4D, mask=None):
    csv_fluorescence = os.path.join(srcDir,
                                    "%s_fluorescence.csv" % series_name)
    if not os.path.exists(csv_fluorescence):
        # Generate projection over time (the img3D) and extract peaks with difference of Gaussian using the params
        # (Will check if file for projection over time exists and just load it)
        img3D_filepath = os.path.join(
            srcDir, "%s_4D-to-3D_max_projection.zip" % series_name)
        img3D, peaks, spheresRAI, impSpheres = findNucleiByMaxProjection(
            img4D, params, img3D_filepath, show=True)
        comp = showAsComposite([wrap(img3D), impSpheres])
        # Measure intensity over time, for every peak
        # by averaging the signal within a radius of each peak.
        measurement_radius = somaDiameter / 3.0
        spheres = [
            ClosedWritableSphere([peak.getFloatPosition(d)
                                  for d in xrange(3)], measurement_radius)
            for peak in peaks
        ]
        insides = [
            Regions.iterable(
                Views.interval(
                    Views.raster(Masks.toRealRandomAccessible(sphere)),
                    Intervals.largestContainedInterval(sphere)))
            for sphere in spheres
        ]

        count = float(Regions.countTrue(insides[0]))  # same for all
        measurements = []

        with open(csv_fluorescence, 'w') as csvfile:
            w = csv.writer(csvfile,
                           delimiter=",",
                           quotechar='"',
                           quoting=csv.QUOTE_NONNUMERIC)
            # Header: with peak coordinates
            w.writerow(["timepoint"] + [
                "%.2f::%.2f::%.2f" %
                tuple(peak.getFloatPosition(d) for d in xrange(3))
                for peak in peaks
            ])
            # Each time point
            for t in xrange(img4D.dimension(3)):
                img3D = Views.hyperSlice(img4D, 3, t)
                mean_intensities = array(
                    ((sum(t.get()
                          for t in Regions.sample(inside, img3D)) / count)
                     for inside in insides), 'f')
                w.writerow([t] + mean_intensities.tolist())
                measurements.append(mean_intensities)

    else:
        # Parse CSV file
        with open(csv_fluorescence, 'r') as csvfile:
            reader = csv.reader(csvfile, delimiter=',', quotechar='"')
            header = reader.next()
            # Parse header, containing peak locations
            peaks = [
                RealPoint.wrap(map(float, h.split("::")))
                for h in islice(header, 1, None)
            ]
            # Parse rows
            measurements = [map(float, islice(row, 1, None)) for row in reader]

    return peaks, measurements
Exemplo n.º 20
0
array_size = len(pixel_array)
print array_size, "<", img_size
print "Proportion:", array_size / float(
    img_size), "AKA", img_size / array_size, "x"

# Add some data to it
center = img.dimension(0) / 2, img.dimension(1) / 2
for z in xrange(img.dimension(2)):
    radius = img.dimension(0) * 0.5 / (z + 1)
    circle = GeomMasks.openSphere(center, radius)
    # Works, explicit iteration of every pixel
    #for t in Regions.sample(circle, Views.hyperSlice(img, 2, z)):
    #  t.setOne()
    # Works: about twice as fast -- measured with: from time import time .... t0 = time(); ... t1 = time()
    deque(imap(BitType.setOne,
               Regions.sample(circle, Views.hyperSlice(img, 2, z))),
          maxlen=0)

# Write as TIFF file
filepath = os.path.join(
    tempfile.gettempdir(),
    "bit-img-" + datetime.now().strftime("%Y-%m-%d-%H:%M:%S") + ".tif")
ra = RandomAccessFile(filepath, 'rw')
try:
    # Header: big endian (4D, 4D) or (M, M), magic number (42, 42), and offset of 9 bytes to first IFD
    # Note:
    # bin(int("4D", 16))[2:].zfill(8) == '01001101'
    # int("4D", 16) == 77
    ra.write(array([77, 77, 0, 42, 0, 0, 0, 8], 'b'))
    # A tmp plane img to copy into it each 2D slice for saving later as the pixel data of each IFD
    plane_img = ArrayImgs.bits([img.dimension(0), img.dimension(1)])
Exemplo n.º 21
0
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)
    # Views of the 3 color channels, as extended and interpolatable
    channels = [
        Views.interpolate(
            Views.extendZero(Converters.argbChannel(imgSlice1, i)),
            NLinearInterpolatorFactory()) for i in [1, 2, 3]
    ]
    # ARGBType 2D view of the transformed color channels
    imgSlice2 = Converters.mergeARGB(
        Views.stack(
            Views.interval(RealViews.transform(channel, transform),
                           sliceInterval)
            for channel in channels), ColorChannelOrder.RGB)
    slices2.append(imgSlice2)

# Transformed view