示例#1
0
def _test():
    """Tests for the Resampling Module"""
    import ClearMap.Alignment.Resampling as self
    reload(self)
    from ClearMap.Settings import ClearMapPath as basedir
    import iDISCO.IO.IO as io
    import os, numpy

    fn = os.path.join(
        basedir,
        'Test/Data/OME/16-17-27_0_8X-s3-20HF_UltraII_C00_xyz-Table Z\d{4}.ome.tif'
    )
    outfn = os.path.join(basedir, "Test/Data/Resampling/test.mhd")

    print "Making resampled stack " + outfn
    print "source datasize %s" % str(io.dataSize(fn))
    data = self.resampleData(fn,
                             sink=None,
                             resolutionSource=(1, 1, 1),
                             orientation=(1, 2, 3),
                             resolutionSink=(10, 10, 2))
    print data.shape
    io.writeData(outfn, data)

    data = self.resampleData(fn,
                             sink=None,
                             dataSizeSink=(50, 70, 10),
                             orientation=(1, 2, 3))
    print data.shape
    io.writeData(outfn, data)

    dataSizeSource, dataSizeSink, resolutionSource, resolutionSink = self.resampleDataSize(
        dataSizeSource=(100, 200, 303),
        dataSizeSink=None,
        resolutionSource=(1, 1, 1),
        resolutionSink=(5, 5, 5),
        orientation=(1, 2, 3))

    print dataSizeSource, dataSizeSink, resolutionSource, resolutionSink

    points = numpy.array([[0, 0, 0], [1, 1, 1],
                          io.dataSize(fn)])
    points = points.astype('float')
    pr = self.resamplePoints(points,
                             dataSizeSource=fn,
                             dataSizeSink=(50, 70, 10),
                             orientation=(1, 2, 3))
    print pr

    pri = self.resamplePointsInverse(pr,
                                     dataSizeSource=fn,
                                     dataSizeSink=(50, 70, 10),
                                     orientation=(-1, 2, 3))
    print pri

    result = self.resampleDataInverse(
        outfn,
        os.path.join(basedir, 'Test/Data/OME/resample_\d{4}.ome.tif'),
        dataSizeSource=fn)
    print result
示例#2
0
def voxelizeOrientations(points,
                         orientations,
                         dataSize=None,
                         sink=None,
                         size=(5, 5, 5),
                         weights=None):
    """Converts a list of points into an volumetric image array
    
    Arguments:
        points (array): point data array
        orientations (array): point data array
        dataSize (tuple): size of final image
        sink (str, array or None): the location to write or return the resulting voxelization image, if None return array    
    Returns:
        (array): volumetric data of orientation statistics
    """

    if dataSize is None:
        dataSize = tuple(
            int(math.ceil(points[:, i].max())) for i in range(points.shape[1]))
    elif isinstance(dataSize, str):
        dataSize = io.dataSize(dataSize)

    if weights is not None:
        orts = (orientations.T * weights).T
    else:
        orts = orientations

    data = orc.voxelizeOrientations(points, orts, dataSize[0], dataSize[1],
                                    dataSize[2], size[0], size[1], size[2])

    return data
示例#3
0
def _test():
    """Tests for the Resampling Module"""
    import ClearMap.Alignment.Resampling as self
    reload(self)
    from ClearMap.Settings import ClearMapPath as basedir 
    import iDISCO.IO.IO as io
    import os, numpy

    fn = os.path.join(basedir, 'Test/Data/OME/16-17-27_0_8X-s3-20HF_UltraII_C00_xyz-Table Z\d{4}.ome.tif');
    outfn = os.path.join(basedir, "Test/Data/Resampling/test.mhd")
    
    print "Making resampled stack " + outfn
    print "source datasize %s" % str(io.dataSize(fn));
    data = self.resampleData(fn, sink = None, resolutionSource = (1,1,1), orientation = (1,2,3), resolutionSink = (10,10,2));
    print data.shape
    io.writeData(outfn, data)   

    data = self.resampleData(fn, sink = None, dataSizeSink = (50,70,10), orientation = (1,2,3));
    print data.shape
    io.writeData(outfn, data)   


    dataSizeSource, dataSizeSink, resolutionSource, resolutionSink = self.resampleDataSize(dataSizeSource = (100,200, 303), dataSizeSink = None, 
                                                                                      resolutionSource = (1,1,1), resolutionSink = (5,5,5), orientation = (1,2,3));

    print dataSizeSource, dataSizeSink, resolutionSource, resolutionSink
    

    points = numpy.array([[0,0,0], [1,1,1], io.dataSize(fn)]);
    points = points.astype('float')
    pr = self.resamplePoints(points, dataSizeSource = fn, dataSizeSink = (50,70,10), orientation = (1,2,3))
    print pr

    pri = self.resamplePointsInverse(pr, dataSizeSource = fn, dataSizeSink = (50,70,10), orientation = (-1,2,3))
    print pri


    result = self.resampleDataInverse(outfn, os.path.join(basedir, 'Test/Data/OME/resample_\d{4}.ome.tif'), dataSizeSource = fn);
    print result
示例#4
0
def resamplePointsInverse(pointSource,
                          pointSink=None,
                          dataSizeSource=None,
                          dataSizeSink=None,
                          orientation=None,
                          resolutionSource=(4.0625, 4.0625, 3),
                          resolutionSink=(25, 25, 25),
                          **args):
    """Resample points from the coordinates of the resampled image to the original data

    The resampling of points here corresponds to he resampling of an image in :func:`resampleDataInverse`
        
    Arguments:
        pointSource (str or array): image to be resampled
        pointSink (str or None): destination of resampled image
        orientation (tuple): orientation specified by permuation and change in sign of (1,2,3)
        dataSizeSource (str, tuple or None): size of the data source
        dataSizeSink (str, tuple or None): target size of the resampled image
        resolutionSource (tuple): resolution of the source image (in length per pixel)
        resolutionSink (tuple): resolution of the resampled image (in length per pixel)
        
    Returns:
        (array or str): data or file name of inversely resampled points

    Notes: 
        * resolutions are assumed to be given for the axes of the intrinsic 
          orientation of the data and reference as when viewed by matplotlib or ImageJ
        * orientation: permuation of 1,2,3 with potential sign, indicating which 
          axes map onto the reference axes, a negative sign indicates reversal 
          of that particular axes
        * only a minimal set of information to detremine the resampling parameter 
          has to be given, e.g. dataSizeSource and dataSizeSink
    """

    orientation = fixOrientation(orientation)

    #datasize of data source
    if isinstance(dataSizeSource, basestring):
        dataSizeSource = io.dataSize(dataSizeSource)

    dataSizeSource, dataSizeSink, resolutionSource, resolutionSink = resampleDataSize(
        dataSizeSource=dataSizeSource,
        dataSizeSink=dataSizeSink,
        resolutionSource=resolutionSource,
        resolutionSink=resolutionSink,
        orientation=orientation)

    points = io.readPoints(pointSource)

    dataSizeSinkI = orientDataSizeInverse(dataSizeSink, orientation)
    #resolutionSinkI = orientResolutionInverse(resolutionSink, orientation);

    #scaling factors
    scale = [
        float(dataSizeSource[i]) / float(dataSizeSinkI[i]) for i in range(3)
    ]
    #print scale

    rpoints = points.copy()

    #invert axis inversion and permutations
    if not orientation is None:
        #invert permuation
        iorientation = inverseOrientation(orientation)
        per = orientationToPermuation(iorientation)
        rpoints = rpoints[:, per]

        for i in range(3):
            if iorientation[i] < 0:
                rpoints[:, i] = dataSizeSinkI[i] - rpoints[:, i]

    #scale points
    for i in range(3):
        rpoints[:, i] = rpoints[:, i] * scale[i]

    return io.writePoints(pointSink, rpoints)
示例#5
0
def resampleDataInverse(sink,
                        source=None,
                        dataSizeSource=None,
                        orientation=None,
                        resolutionSource=(4.0625, 4.0625, 3),
                        resolutionSink=(25, 25, 25),
                        processingDirectory=None,
                        processes=1,
                        cleanup=True,
                        verbose=True,
                        interpolation='linear',
                        **args):
    """Resample data inversely to :func:`resampleData` routine
    
    Arguments:
        sink (str or None): image to be inversly resampled (=sink in :func:`resampleData`)
        source (str or array): destination for inversly resmapled image (=source in :func:`resampleData`)
        dataSizeSource (tuple or None): target size of the resampled image
        orientation (tuple): orientation specified by permuation and change in sign of (1,2,3)
        resolutionSource (tuple): resolution of the source image (in length per pixel)
        resolutionSink (tuple): resolution of the resampled image (in length per pixel)
        processingDirectory (str or None): directory in which to perform resmapling in parallel, None a temporary directry will be created
        processes (int): number of processes to use for parallel resampling
        cleanup (bool): remove temporary files
        verbose (bool): display progress information
        interpolation (str): method to use for interpolating to the resmapled image
    
    Returns:
        (array or str): data or file name of resampled image

    Notes: 
        * resolutions are assumed to be given for the axes of the intrinsic 
          orientation of the data and reference as when viewed by matplotlib or ImageJ
        * orientation: permuation of 1,2,3 with potential sign, indicating which 
          axes map onto the reference axes, a negative sign indicates reversal 
          of that particular axes
        * only a minimal set of information to detremine the resampling parameter 
          has to be given, e.g. dataSizeSource and dataSizeSink
    """

    #orientation
    orientation = fixOrientation(orientation)

    #assume we can read data fully into memory
    resampledData = io.readData(sink)

    dataSizeSink = resampledData.shape

    if isinstance(dataSizeSource, basestring):
        dataSizeSource = io.dataSize(dataSizeSource)

    dataSizeSource, dataSizeSink, resolutionSource, resolutionSink = resampleDataSize(
        dataSizeSource=dataSizeSource,
        dataSizeSink=dataSizeSink,
        resolutionSource=resolutionSource,
        resolutionSink=resolutionSink,
        orientation=orientation)

    #print (dataSizeSource, dataSizeSink, resolutionSource, resolutionSink )

    dataSizeSinkI = orientDataSizeInverse(dataSizeSink, orientation)

    #flip axes back and permute inversely
    if not orientation is None:
        if orientation[0] < 0:
            resampledData = resampledData[::-1, :, :]
        if orientation[1] < 0:
            resampledData = resampledData[:, ::-1, :]
        if orientation[2] < 0:
            resampledData = resampledData[:, :, ::-1]

        #reorient
        peri = inverseOrientation(orientation)
        peri = orientationToPermuation(peri)
        resampledData = resampledData.transpose(peri)

    # upscale in z
    interpolation = fixInterpolation(interpolation)

    resampledDataXY = numpy.zeros(
        (dataSizeSinkI[0], dataSizeSinkI[1], dataSizeSource[2]),
        dtype=resampledData.dtype)

    for i in range(dataSizeSinkI[0]):
        if verbose and i % 25 == 0:
            print "resampleDataInverse: processing %d/%d" % (i,
                                                             dataSizeSinkI[0])

        #cv2.resize takes reverse order of sizes !
        resampledDataXY[i, :, :] = cv2.resize(
            resampledData[i, :, :], (dataSizeSource[2], dataSizeSinkI[1]),
            interpolation=interpolation)

    # upscale x, y in parallel

    if io.isFileExpression(source):
        files = source
    else:
        if processingDirectory == None:
            processingDirectory = tempfile.mkdtemp()
        files = os.path.join(sink[0], 'resample_\d{4}.tif')

    io.writeData(files, resampledDataXY)

    nZ = dataSizeSource[2]
    pool = multiprocessing.Pool(processes=processes)
    argdata = []
    for i in range(nZ):
        argdata.append((source, fl.fileExpressionToFileName(files, i),
                        dataSizeSource, interpolation, i, nZ))
    pool.map(_resampleXYParallel, argdata)

    if io.isFileExpression(source):
        return source
    else:
        data = io.convertData(files, source)

        if cleanup:
            shutil.rmtree(processingDirectory)

        return data
示例#6
0
def resampleData(source,
                 sink=None,
                 orientation=None,
                 dataSizeSink=None,
                 resolutionSource=(4.0625, 4.0625, 3),
                 resolutionSink=(25, 25, 25),
                 processingDirectory=None,
                 processes=1,
                 cleanup=True,
                 verbose=True,
                 interpolation='linear',
                 **args):
    """Resample data of source in resolution and orientation
    
    Arguments:
        source (str or array): image to be resampled
        sink (str or None): destination of resampled image
        orientation (tuple): orientation specified by permuation and change in sign of (1,2,3)
        dataSizeSink (tuple or None): target size of the resampled image
        resolutionSource (tuple): resolution of the source image (in length per pixel)
        resolutionSink (tuple): resolution of the resampled image (in length per pixel)
        processingDirectory (str or None): directory in which to perform resmapling in parallel, None a temporary directry will be created
        processes (int): number of processes to use for parallel resampling
        cleanup (bool): remove temporary files
        verbose (bool): display progress information
        interpolation (str): method to use for interpolating to the resmapled image
    
    Returns:
        (array or str): data or file name of resampled image

    Notes: 
        * resolutions are assumed to be given for the axes of the intrinsic 
          orientation of the data and reference as when viewed by matplotlib or ImageJ
        * orientation: permuation of 1,2,3 with potential sign, indicating which 
          axes map onto the reference axes, a negative sign indicates reversal 
          of that particular axes
        * only a minimal set of information to detremine the resampling parameter 
          has to be given, e.g. dataSizeSource and dataSizeSink
    """

    orientation = fixOrientation(orientation)

    if isinstance(dataSizeSink, basestring):
        dataSizeSink = io.dataSize(dataSizeSink)

    #orient actual resolutions onto reference resolution
    dataSizeSource = io.dataSize(source)

    dataSizeSource, dataSizeSink, resolutionSource, resolutionSink = resampleDataSize(
        dataSizeSource=dataSizeSource,
        dataSizeSink=dataSizeSink,
        resolutionSource=resolutionSource,
        resolutionSink=resolutionSink,
        orientation=orientation)

    dataSizeSinkI = orientDataSizeInverse(dataSizeSink, orientation)

    #print dataSizeSource, dataSizeSink, resolutionSource, resolutionSink, dataSizeSinkI

    #rescale in x y in parallel
    if processingDirectory == None:
        processingDirectory = tempfile.mkdtemp()

    interpolation = fixInterpolation(interpolation)

    nZ = dataSizeSource[2]
    pool = multiprocessing.Pool(processes=processes)
    argdata = []
    for i in range(nZ):
        argdata.append(
            (source, os.path.join(processingDirectory,
                                  'resample_%04d.tif' % i), dataSizeSinkI,
             interpolation, i, nZ, verbose))
        #print argdata[i]
    pool.map(_resampleXYParallel, argdata)

    #rescale in z
    fn = os.path.join(processingDirectory, 'resample_%04d.tif' % 0)
    data = io.readData(fn)
    zImage = numpy.zeros((dataSizeSinkI[0], dataSizeSinkI[1], nZ),
                         dtype=data.dtype)
    for i in range(nZ):
        if verbose and i % 10 == 0:
            print "resampleData; reading %d/%d" % (i, nZ)
        fn = os.path.join(processingDirectory, 'resample_%04d.tif' % i)
        zImage[:, :, i] = io.readData(fn)

    resampledData = numpy.zeros(dataSizeSinkI, dtype=zImage.dtype)

    for i in range(dataSizeSinkI[0]):
        if verbose and i % 25 == 0:
            print "resampleData: processing %d/%d" % (i, dataSizeSinkI[0])
        #resampledImage[:, iImage ,:] =  scipy.misc.imresize(zImage[:,iImage,:], [resizedZAxisSize, sagittalImageSize[1]] , interp = 'bilinear');
        #cv2.resize takes reverse order of sizes !
        resampledData[i, :, :] = cv2.resize(
            zImage[i, :, :], (dataSizeSinkI[2], dataSizeSinkI[1]),
            interpolation=interpolation)
        #resampledData[i ,:, :] =  cv2.resize(zImage[i,:, :], (dataSize[1], resizedZSize));

    #account for using (z,y,x) array representation -> (y,x,z)
    #resampledData = resampledData.transpose([1,2,0]);
    #resampledData = resampledData.transpose([2,1,0]);

    if cleanup:
        shutil.rmtree(processingDirectory)

    if not orientation is None:

        #reorient
        per = orientationToPermuation(orientation)
        resampledData = resampledData.transpose(per)

        #reverse orientation after permuting e.g. (-2,1) brings axis 2 to first axis and we can reorder there
        if orientation[0] < 0:
            resampledData = resampledData[::-1, :, :]
        if orientation[1] < 0:
            resampledData = resampledData[:, ::-1, :]
        if orientation[2] < 0:
            resampledData = resampledData[:, :, ::-1]

        #bring back from y,x,z to z,y,x
        #resampledImage = resampledImage.transpose([2,0,1]);
    if verbose:
        print "resampleData: resampled data size: " + str(resampledData.shape)

    if sink == []:
        if io.isFileExpression(source):
            sink = os.path.split(source)
            sink = os.path.join(sink[0], 'resample_\d{4}.tif')
        elif isinstance(source, basestring):
            sink = source + '_resample.tif'
        else:
            raise RuntimeError(
                'resampleData: automatic sink naming not supported for non string source!'
            )

    return io.writeData(sink, resampledData)
示例#7
0
def xmlImportFile(regularExpression, size = None, overlap = None, addOverlap = 0, origin = None, resolution = None, tiling = None, tileExpression = None, zRange = None, xmlImportFile = None, asString = False):
  """Creates the xml import file for TeraStitcher from a directory of image files and optional additional information

  Arguments:
    regularExpression (string): base directory or regular expression to infer the tiled image data, in the latter case use group names
                                names 'col' and 'row' for the tile indices and 'z' for the z-plane indices
    size (tuple or None): volume size in pixel if None inferred from meta data
    overlap (tuple or None): the (x,y) overlap of the tiles in pixel, if None try to find info from metadata
    addOverlapp (tuple): additional overlap in pixel to increase posssible search radius
    origin (tuple or None): the origin of the image, if None then the tpypical value (0.0,0.0,0.0).
    resolution (tupl0 or None): the (x,y,z) resolution of the image in microns per pixel, if None try to find info from metadata
    tiling (tuple or  None): the (row,col) tiling dimensions, if None infer from 'row' and 'col' groups in regularExpression
    tileExpression (function or None): a function of (col,row) that returns a regular expression for the images in the (col,row) tile or None if that tile is missing, 
                                       if None use the regular expression row and col group info
    zRange (function or None. all): a function of (col,row) that returns a the z range specifications for the (col,row) tile
                                    if None use the regular expression z group to infer this from first tile, if all infer this in detail for all tiles             
    xmlImportFile (string or None): filename for the xml import file, if None return the xml tree, if all create 'TreaStitcher_import.xml' file in base directory
    asString (bool): if True return xml code as string, otherwise return as a xml tree
    
  Returns:
    string: filename of the xml import file
    
  Note:
    Example for a regular expression: r'/path/to/image/image_(?P<row>\d{2})_(?P<col>\d{2})_(?P<z>\d{4}).tif'
    
  See also:
    :func:`importData`
  """
  
  ## origin
  if origin is None:
    origin = (0,0,0);
  
  
  #infer size, resolution and overlap
  if size is None or resolution is None or overlap is None:
    firstFile = findFirstFile(regularExpression);
    finfo = findFileInfo(firstFile);
    
    if size is None:
      size = finfo['size'];
  
    if resolution is None:
      resolution = finfo['resolution'];
      
    if overlap is None:
      overlap = finfo['overlap'];
    
    for val, name in zip([size, overlap, resolution],['size', 'overlap', 'resolution']) :
      if val is None:
        raise RuntimeError('cannot determine %s from file or input!' % name);
  

  if tiling is None or zRange is None or zRange is all:
    #infer tiling from regular expression
    
    #find file:

    fns, ids = findFileList(regularExpression, groups = ('row', 'col', 'z'));
    fsize = io.dataSize(fns[0]);
    dim = len(fsize);
    
    #print fns
    #print ids
    ids = np.array(ids);
    
    # get rid of invalid labels
    b = np.zeros(ids.shape[0], dtype = bool);
    for i in range(5 - dim):
      b = np.logical_or(b, np.equal(ids[:,i], None)) 
    b = np.logical_not(b);
    fns = fns[b];
    ids = ids[b];
    
    if len(fns) == 0:
      raise RuntimeError('no files found that match the expression %s with row, col and z groups' % regularExpression);
    
    # calculate tile dimensions
    rows = np.unique(ids[:,0]);
    nrows = len(rows);
    
    cols = np.unique(ids[:,1]);
    ncols = len(cols);
    
    if tiling is not None and tiling != (nrows, ncols):
      raise RuntimeWarning('specified tiling is different from inferred tiling, min tile number will be used !');
      tiling = (min(nrows, tiling[0]), min(ncols, tiling[1]));
      rows = rows[:tiling[0]];
      cols = cols[:tiling[1]];
    else:
      tiling = (nrows, ncols);
    
    # zRanges
    if dim == 2:
      zs  = np.unique(ids[:,2]);
      nzs = len(zs);
      
      if zRange is None:
        zRange = (0, nzs);
      elif zRange is all:
        zRange = lambda row,col: (0, np.sum(np.logical_and(ids[:,0] == row, ids[:,1] == col)));
    else:
      nzs = fsize[2];
      zRange = (0, nzs);
  
  else:
    rows = None;
    cols = None;
    fns = None;
    
    nzs = 0;
    for row in range(tiling[0]):
      for col in range(tiling[1]):
        nzs = max(nzs, zRange(row,col)[1]);
    
  size = tuple(size) + (nzs,);
  
  #base directory and tile directories
  if fns is None:
    if firstFile is None:
      fn = findFirstFile(regularExpression, sort = False);
    else:
      fn = firstFile;
  else:
    fn = fns[0];
    
  fdim = len(io.dataSize(fn));
  
  fnsep = fn.split(os.path.sep);
  fesep = regularExpression.split(os.path.sep);
  
  if len(fnsep) != len(fesep):
    raise RuntimeError('inconsistent file names and file expression!');
  
  for i in range(len(fnsep)):
    if fnsep[i] != fesep[i]:
      baseDirectory = os.path.sep.join(fesep[:i]);
      regularExpression = os.path.sep.join(fesep[i:]);
      break;
  
  #tileExpression
  if tileExpression is None:
    def makeTileExpression(row,col):
      te = re.sub(r'\(\?\P\<row\>.*?\)', str(row), regularExpression, count = 1);
      return re.sub(r'\(\?\P\<col\>.*?\)', str(col), te, count = 1);
    tileExpression = makeTileExpression;
  elif isinstance(tileExpression, str):
    tileExpressionString = tileExpression;
    def makeTileExpression(row,col):
      te = re.sub(r'\(\?\P\<row\>.*?\)', str(row), tileExpressionString, count = 1);
      return re.sub(r'\(\?\P\<col\>.*?\)', str(col), te, count = 1);
    tileExpression = makeTileExpression;
  
  # create xml import   
  return xmlImport(baseDirectory, size = size, resolution = resolution, origin = origin, overlap = overlap, addOverlap = addOverlap,
                   tiling = tiling, tileExpression = tileExpression, zRange = zRange, rows = rows, cols = cols, dim = fdim,
                   xmlImportFile = xmlImportFile, asString = asString);
示例#8
0
def findFileInfo(filename):
  """Tries to infer relevant information from filename for tiling / stitching
  
  Arguments:
    filename (str): filename to infer information from
    
  Returns:
    dict: dictionary with relavant information: resolution (microns per pixel), overlap (microns), size (pixel)
    
  Note:
    resolution is in microns per pixel, overlap is in microns and size is in pixel
  """
  #TODO: move this to the individual file readers  
  
  #this is for ome tif images
  from PIL import Image
  from PIL.ExifTags import TAGS
     
  def ome_info(fn):
      ret = {}
      i = Image.open(fn)
      Dict = {}
      for m,n in zip(i.tag.keys(),i.tag.values()) :
          Dict[m] = n
      #info = i.tag.as_dict();
      for tag, value in Dict.iteritems():
          decoded = TAGS.get(tag)
          ret[decoded] = value
      return ret
      
  imginfo = ome_info(filename);
  keys = imginfo.keys();
  
  finfo = {'resolution' : None, 'overlap' : None, 'size' : None};
  
  # get image sizes  
  if ('ImageHeight' in keys) and ('ImageWidth' in keys):
    finfo['size'] = (imginfo['ImageWidth'], imginfo['ImageHeight']);
  else:
    finfo['size'] = io.dataSize(filename)
  
  
  if 'ImageDescription' in keys:
    imgxml = imginfo['ImageDescription'];
    if isinstance(imgxml, tuple):
      imgxml = imgxml[0];

    try:
      imgxml = etree.fromstring(str(imgxml));
    except:
      imgxml = _cleanXML(imgxml); # for large images the TileConfiguration entry is huge and can cause a AttValue error in the xml parser
      imgxml = etree.fromstring(str(imgxml));
    
    # get resolution
    pix = [x for x in imgxml.iter('{*}Pixels')];
    if len(pix)> 0:
      pix = pix[0].attrib;
      keys = pix.keys();
      if 'PhysicalSizeX' in keys and 'PhysicalSizeY' in keys and 'PhysicalSizeZ' in keys:
        finfo['resolution'] = (float(pix['PhysicalSizeX']), float(pix['PhysicalSizeY']), float(pix['PhysicalSizeZ']));
  
    # get overlap
    e1 = [x for x in imgxml.iter('{*}xyz-Table_X_Overlap')];
    e2 = [x for x in imgxml.iter('{*}xyz-Table_Y_Overlap')];
    if len(e1) > 0 and len(e2) > 0:
      finfo['overlap'] = (float(e1[0].attrib['Value']), float(e2[0].attrib['Value']));
      
  return finfo;
示例#9
0
def dataViewer(source, axis = None, scale = None):
  source = io.readData(source);
  size = io.dataSize(source);
  size2 = np.array(np.array(size) / 2, dtype = int);
  order = [0,1,2];
  #ImageView expexts z,x,y ordering
  
  #order = np.roll(order, -2)
  source = np.transpose(source, order);
  
  dim = len(size);
  if scale is None:
    scale = np.ones(dim);
  else:
    scale = np.array(scale);
    assert(len(scale) == dim);
  #scale = np.roll(scale,-2);
  
  if axis is None:
    axis = 2;
  orderR  = np.roll(order, -axis);
  sourceR = np.transpose(source, orderR);
  sizeR   = np.roll(size, -axis);
  scaleR  = np.roll(scale,-axis);
  
  print sizeR;
  print scaleR;
    
  #axes = ('t', 'x', 'y');
  axes = None;
  
  percentiles = ([0,5,10,50],[50,90, 95, 100]);
  precent_id = [1, 2];
  
  # create the gui
  pg.mkQApp()  
  
  widget = pg.QtGui.QWidget();
  widget.setWindowTitle('Data Viewer');
  widget.resize(1000,800)  
  
  layout = pg.QtGui.QVBoxLayout();
  layout.setContentsMargins(0,0,0,0)        
  
  splitter = pg.QtGui.QSplitter();
  splitter.setOrientation(pg.QtCore.Qt.Vertical)
  splitter.setSizes([int(widget.height()*0.99), int(widget.height()*0.01)]);
  layout.addWidget(splitter);
  
  #  Image plot
  img = pg.ImageView();
  img.setImage(sourceR, axes = axes);
  img.imageItem.setRect(pg.QtCore.QRect(0, 0, sizeR[1] * scaleR[1],  sizeR[2] * scaleR[2]))
  img.view.setXRange(0, sizeR[1] * scaleR[1]);
  img.view.setYRange(0, sizeR[2] * scaleR[2]);
  img.setCurrentIndex(size2[axis]);
  img.ui.histogram.region.setRegion(np.percentile(sourceR[size2[axis]], [percentiles[0][precent_id[0]], percentiles[1][precent_id[1]]]));
  splitter.addWidget(img);
  
  # Tools
  tools_layout = pg.QtGui.QGridLayout()
  axis_buttons = [];
  for d in range(dim):
    b = pg.QtGui.QPushButton('%d' % (d));
    b.setMaximumWidth(100);
    tools_layout.addWidget(b,0,d);
    axis_buttons.append(b);

  adjust_buttons = [];
  pre = ['Min %d', 'Max %d'];
  iitem = dim;
  for r in range(2):
    adjust_buttons_mm = [];
    for p in percentiles[r]:
      b = pg.QtGui.QPushButton(pre[r] % (p));
      b.setMaximumWidth(120);
      tools_layout.addWidget(b,0,iitem);
      iitem +=1;
      adjust_buttons_mm.append(b);
    adjust_buttons.append(adjust_buttons_mm);
  
  tools_widget = pg.QtGui.QWidget();
  tools_widget.setLayout(tools_layout);
  splitter.addWidget(tools_widget);
  
  widget.setLayout(layout)
  widget.show();
  
  # Callbacks for handling user interaction
  def updateAxis(a):
    axis = a;
    orderR  = np.roll(order, -axis);
    sourceR = np.transpose(source, orderR);
    sizeR   = np.roll(size, -axis);
    scaleR  = np.roll(scale,-axis);
    img.setImage(sourceR, axes = axes);
    img.imageItem.setRect(pg.QtCore.QRect(0, 0, sizeR[1] * scaleR[1],  sizeR[2] * scaleR[2]))
    img.view.setXRange(0, sizeR[1] * scaleR[1]);
    img.view.setYRange(0, sizeR[2] * scaleR[2]);
    img.setCurrentIndex(size2[axis]);
    img.ui.histogram.region.setRegion(np.percentile(sourceR[size2[axis]], [percentiles[0][precent_id[0]], percentiles[1][precent_id[1]]]));
  
  for i,ab in enumerate(axis_buttons):
    ab.clicked.connect(partial(updateAxis, i));
  
  def updateRegion(m,p):
    precent_id[m] = p;
    img.ui.histogram.region.setRegion(np.percentile(sourceR[size2[axis]], [percentiles[0][precent_id[0]], percentiles[1][precent_id[1]]]));
    
  for m,ab in enumerate(adjust_buttons):
    for p, abm in enumerate(ab):
      abm.clicked.connect(partial(updateRegion, m, p));
  
  return widget;
示例#10
0
def resamplePointsInverse(pointSource, pointSink = None, dataSizeSource = None, dataSizeSink = None, orientation = None, resolutionSource = (4.0625, 4.0625, 3), resolutionSink = (25, 25, 25), **args):
    """Resample points from the coordinates of the resampled image to the original data

    The resampling of points here corresponds to he resampling of an image in :func:`resampleDataInverse`
        
    Arguments:
        pointSource (str or array): image to be resampled
        pointSink (str or None): destination of resampled image
        orientation (tuple): orientation specified by permuation and change in sign of (1,2,3)
        dataSizeSource (str, tuple or None): size of the data source
        dataSizeSink (str, tuple or None): target size of the resampled image
        resolutionSource (tuple): resolution of the source image (in length per pixel)
        resolutionSink (tuple): resolution of the resampled image (in length per pixel)
        
    Returns:
        (array or str): data or file name of inversely resampled points

    Notes: 
        * resolutions are assumed to be given for the axes of the intrinsic 
          orientation of the data and reference as when viewed by matplotlib or ImageJ
        * orientation: permuation of 1,2,3 with potential sign, indicating which 
          axes map onto the reference axes, a negative sign indicates reversal 
          of that particular axes
        * only a minimal set of information to detremine the resampling parameter 
          has to be given, e.g. dataSizeSource and dataSizeSink
    """
       
    orientation = fixOrientation(orientation);
    
    #datasize of data source
    if isinstance(dataSizeSource, basestring):
        dataSizeSource = io.dataSize(dataSizeSource);
    
    dataSizeSource, dataSizeSink, resolutionSource, resolutionSink = resampleDataSize(dataSizeSource = dataSizeSource, dataSizeSink = dataSizeSink, 
                                                                                      resolutionSource = resolutionSource, resolutionSink = resolutionSink, orientation = orientation);
            
    points = io.readPoints(pointSource);
    
    dataSizeSinkI = orientDataSizeInverse(dataSizeSink, orientation);
    #resolutionSinkI = orientResolutionInverse(resolutionSink, orientation);
        
    #scaling factors
    scale = [float(dataSizeSource[i]) / float(dataSizeSinkI[i]) for i in range(3)];
    #print scale

    rpoints = points.copy();    
    
    #invert axis inversion and permutations    
    if not orientation is None:
        #invert permuation
        iorientation = inverseOrientation(orientation);
        per = orientationToPermuation(iorientation);
        rpoints = rpoints[:,per];
        
        for i in range(3):
            if iorientation[i] < 0:
                rpoints[:,i] = dataSizeSinkI[i] - rpoints[:,i];
    
    #scale points
    for i in range(3):   
        rpoints[:,i] = rpoints[:,i] * scale[i];    
    
    return io.writePoints(pointSink, rpoints);
示例#11
0
def resampleDataInverse(sink, source = None, dataSizeSource = None, orientation = None, resolutionSource = (4.0625, 4.0625, 3), resolutionSink = (25, 25, 25), 
                        processingDirectory = None, processes = 1, cleanup = True, verbose = True, interpolation = 'linear', **args):
    """Resample data inversely to :func:`resampleData` routine
    
    Arguments:
        sink (str or None): image to be inversly resampled (=sink in :func:`resampleData`)
        source (str or array): destination for inversly resmapled image (=source in :func:`resampleData`)
        dataSizeSource (tuple or None): target size of the resampled image
        orientation (tuple): orientation specified by permuation and change in sign of (1,2,3)
        resolutionSource (tuple): resolution of the source image (in length per pixel)
        resolutionSink (tuple): resolution of the resampled image (in length per pixel)
        processingDirectory (str or None): directory in which to perform resmapling in parallel, None a temporary directry will be created
        processes (int): number of processes to use for parallel resampling
        cleanup (bool): remove temporary files
        verbose (bool): display progress information
        interpolation (str): method to use for interpolating to the resmapled image
    
    Returns:
        (array or str): data or file name of resampled image

    Notes: 
        * resolutions are assumed to be given for the axes of the intrinsic 
          orientation of the data and reference as when viewed by matplotlib or ImageJ
        * orientation: permuation of 1,2,3 with potential sign, indicating which 
          axes map onto the reference axes, a negative sign indicates reversal 
          of that particular axes
        * only a minimal set of information to detremine the resampling parameter 
          has to be given, e.g. dataSizeSource and dataSizeSink
    """    
    
    
    #orientation
    orientation = fixOrientation(orientation);
    
    #assume we can read data fully into memory
    resampledData = io.readData(sink);

    dataSizeSink = resampledData.shape;
    
    if isinstance(dataSizeSource, basestring):
        dataSizeSource = io.dataSize(dataSizeSource);

    dataSizeSource, dataSizeSink, resolutionSource, resolutionSink = resampleDataSize(dataSizeSource = dataSizeSource, dataSizeSink = dataSizeSink, 
                                                                                      resolutionSource = resolutionSource, resolutionSink = resolutionSink, orientation = orientation);

    #print (dataSizeSource, dataSizeSink, resolutionSource, resolutionSink )
    
    dataSizeSinkI = orientDataSizeInverse(dataSizeSink, orientation);
    
    
    #flip axes back and permute inversely
    if not orientation is None:
        if orientation[0] < 0:
            resampledData = resampledData[::-1, :, :];
        if orientation[1] < 0:
            resampledData = resampledData[:, ::-1, :]; 
        if orientation[2] < 0:
            resampledData = resampledData[:, :, ::-1];

        
        #reorient
        peri = inverseOrientation(orientation);
        peri = orientationToPermuation(peri);
        resampledData = resampledData.transpose(peri);
    
    # upscale in z
    interpolation = fixInterpolation(interpolation);
    
    resampledDataXY = numpy.zeros((dataSizeSinkI[0], dataSizeSinkI[1], dataSizeSource[2]), dtype = resampledData.dtype);    
    
    for i in range(dataSizeSinkI[0]):
        if verbose and i % 25 == 0:
            print "resampleDataInverse: processing %d/%d" % (i, dataSizeSinkI[0])

        #cv2.resize takes reverse order of sizes !
        resampledDataXY[i ,:, :] =  cv2.resize(resampledData[i,:,:], (dataSizeSource[2], dataSizeSinkI[1]), interpolation = interpolation);

    # upscale x, y in parallel
    
    if io.isFileExpression(source):
        files = source;
    else:
        if processingDirectory == None:
            processingDirectory = tempfile.mkdtemp();   
        files = os.path.join(sink[0], 'resample_\d{4}.tif');
    
    io.writeData(files, resampledDataXY);
    
    nZ = dataSizeSource[2];
    pool = multiprocessing.Pool(processes=processes);
    argdata = [];
    for i in range(nZ):
        argdata.append( (source, fl.fileExpressionToFileName(files, i), dataSizeSource, interpolation, i, nZ) );  
    pool.map(_resampleXYParallel, argdata);
    
    if io.isFileExpression(source):
        return source;
    else:
        data = io.convertData(files, source);
        
        if cleanup:
            shutil.rmtree(processingDirectory);
        
        return data;
示例#12
0
def resampleData(source, sink = None,  orientation = None, dataSizeSink = None, resolutionSource = (4.0625, 4.0625, 3), resolutionSink = (25, 25, 25), 
                 processingDirectory = None, processes = 1, cleanup = True, verbose = True, interpolation = 'linear', **args):
    """Resample data of source in resolution and orientation
    
    Arguments:
        source (str or array): image to be resampled
        sink (str or None): destination of resampled image
        orientation (tuple): orientation specified by permuation and change in sign of (1,2,3)
        dataSizeSink (tuple or None): target size of the resampled image
        resolutionSource (tuple): resolution of the source image (in length per pixel)
        resolutionSink (tuple): resolution of the resampled image (in length per pixel)
        processingDirectory (str or None): directory in which to perform resmapling in parallel, None a temporary directry will be created
        processes (int): number of processes to use for parallel resampling
        cleanup (bool): remove temporary files
        verbose (bool): display progress information
        interpolation (str): method to use for interpolating to the resmapled image
    
    Returns:
        (array or str): data or file name of resampled image

    Notes: 
        * resolutions are assumed to be given for the axes of the intrinsic 
          orientation of the data and reference as when viewed by matplotlib or ImageJ
        * orientation: permuation of 1,2,3 with potential sign, indicating which 
          axes map onto the reference axes, a negative sign indicates reversal 
          of that particular axes
        * only a minimal set of information to detremine the resampling parameter 
          has to be given, e.g. dataSizeSource and dataSizeSink
    """
        
    orientation = fixOrientation(orientation);
    
    if isinstance(dataSizeSink, basestring):
        dataSizeSink = io.dataSize(dataSizeSink);

    #orient actual resolutions onto reference resolution    
    dataSizeSource = io.dataSize(source);
        
    dataSizeSource, dataSizeSink, resolutionSource, resolutionSink = resampleDataSize(dataSizeSource = dataSizeSource, dataSizeSink = dataSizeSink, 
                                                                                      resolutionSource = resolutionSource, resolutionSink = resolutionSink, orientation = orientation);
    
    dataSizeSinkI = orientDataSizeInverse(dataSizeSink, orientation);
    
    #print dataSizeSource, dataSizeSink, resolutionSource, resolutionSink, dataSizeSinkI
    
     
    #rescale in x y in parallel
    if processingDirectory == None:
        processingDirectory = tempfile.mkdtemp();     
        
    interpolation = fixInterpolation(interpolation);
     
    nZ = dataSizeSource[2];
    pool = multiprocessing.Pool(processes=processes);
    argdata = [];
    for i in range(nZ):
        argdata.append( (source, os.path.join(processingDirectory, 'resample_%04d.tif' % i), dataSizeSinkI, interpolation, i, nZ, verbose) );  
        #print argdata[i]
    pool.map(_resampleXYParallel, argdata);
    
    #rescale in z
    fn = os.path.join(processingDirectory, 'resample_%04d.tif' % 0);
    data = io.readData(fn);
    zImage = numpy.zeros((dataSizeSinkI[0], dataSizeSinkI[1], nZ), dtype = data.dtype);    
    for i in range(nZ):
        if verbose and i % 10 == 0:
            print "resampleData; reading %d/%d" % (i, nZ);
        fn = os.path.join(processingDirectory, 'resample_%04d.tif' % i);
        zImage[:,:, i] = io.readData(fn);

    
    resampledData = numpy.zeros(dataSizeSinkI, dtype = zImage.dtype);

    for i in range(dataSizeSinkI[0]):
        if verbose and i % 25 == 0:
            print "resampleData: processing %d/%d" % (i, dataSizeSinkI[0])
        #resampledImage[:, iImage ,:] =  scipy.misc.imresize(zImage[:,iImage,:], [resizedZAxisSize, sagittalImageSize[1]] , interp = 'bilinear'); 
        #cv2.resize takes reverse order of sizes !
        resampledData[i ,:, :] =  cv2.resize(zImage[i,:,:], (dataSizeSinkI[2], dataSizeSinkI[1]), interpolation = interpolation);
        #resampledData[i ,:, :] =  cv2.resize(zImage[i,:, :], (dataSize[1], resizedZSize));
    

    #account for using (z,y,x) array representation -> (y,x,z)
    #resampledData = resampledData.transpose([1,2,0]);
    #resampledData = resampledData.transpose([2,1,0]);
    
    if cleanup:
        shutil.rmtree(processingDirectory);

    if not orientation is None:
        
        #reorient
        per = orientationToPermuation(orientation);
        resampledData = resampledData.transpose(per);
    
        #reverse orientation after permuting e.g. (-2,1) brings axis 2 to first axis and we can reorder there
        if orientation[0] < 0:
            resampledData = resampledData[::-1, :, :];
        if orientation[1] < 0:
            resampledData = resampledData[:, ::-1, :]; 
        if orientation[2] < 0:
            resampledData = resampledData[:, :, ::-1];
        
        #bring back from y,x,z to z,y,x
        #resampledImage = resampledImage.transpose([2,0,1]);
    if verbose:
        print "resampleData: resampled data size: " + str(resampledData.shape)  
    
    if sink == []:
        if io.isFileExpression(source):
            sink = os.path.split(source);
            sink = os.path.join(sink[0], 'resample_\d{4}.tif');
        elif isinstance(source, basestring):
            sink = source + '_resample.tif';
        else:
            raise RuntimeError('resampleData: automatic sink naming not supported for non string source!');
    
    return io.writeData(sink, resampledData);