Esempio n. 1
0
def projectOnSurface(myelin, surface):
    norm = surface.normal()
    vert = surface.vertex()
    Nv = vert.size()

    surfMap = aims.TimeTexture('FLOAT')
    surfMap[0].resize(Nv)
    dx, dy, dz, dt = myelin.getVoxelSize()
    volVox = aims.Volume(myelin.getSizeX(), myelin.getSizeY(),
                         myelin.getSizeZ(), myelin.getSizeT(), 'FLOAT')
    volVox.header().update(myelin.header())
    volVox.fill(0.0)

    print dx, dy, dz

    for i in range(Nv):
        v = vert[i] + t * norm[i]
        x = int(round(v[0] / dx))
        y = int(round(v[1] / dy))
        z = int(round(v[2] / dz))

        val = myelin.value(x, y, z)
        volVox.setValue(val, x, y, z)
        surfMap[0][i] = val
    return surfMap, volVox
Esempio n. 2
0
def convert_raw_map(fname, out_fname):
    '''
    convert one raw map from bdalti (.asc) to .ima format
    '''
    with open(fname) as f:
        lines = f.readlines()

    types = {
        'ncols': int,
        'cellsize': float,
        'xllcorner': float,
        'yllcorner': float,
        'NODATA_value': float,
    }

    metadata = {}
    for l in lines[:6]:
        item = l.strip().split()
        k = item[0]
        metadata[k] = types.get(k, str)(item[1])

    # print(metadata)
    image = aims.Volume((int(metadata['ncols']), int(metadata['nrows'])),
                        dtype='float')
    array = np.asarray(image)
    for i, l in enumerate(lines[6:]):
        array[:, i, 0, 0] = [float(x) for x in l.strip().split()]

    image.header().update(metadata)
    aims.write(image, out_fname)
def relabel_conjunction(labels1, labels2):
    output = aims.Volume(labels1)
    output.fill(0)
    size_x = output.getSizeX()
    size_y = output.getSizeY()
    size_z = output.getSizeZ()
    old_to_new_labels = {}
    next_label = 1
    for z in xrange(size_z):
        for y in xrange(size_y):
            for x in xrange(size_x):
                labels = (labels1.at(x, y, z), labels2.at(x, y, z))
                # Negative means outside propagation region
                if labels[0] < 0 or labels[1] < 0:
                    continue
                # Zeros are failed propagations, they should not be aggregated
                # together
                if labels[0] == 0 or labels[1] == 0:
                    new_label = next_label
                    next_label += 1
                else:
                    try:
                        new_label = old_to_new_labels[labels]
                    except KeyError:
                        new_label = next_label
                        old_to_new_labels[labels] = new_label
                        next_label += 1
                output.setValue(new_label, x, y, z)
    sys.stderr.write("{0}: {1} regions in conjunction\n".format(
        sys.argv[0], next_label - 1))
    return output
Esempio n. 4
0
def make_cortex_sphere_classif(inner_radius,
                               outer_radius,
                               voxel_size,
                               margin=None,
                               noise=None,
                               sigma=None):
    voxel_size = _convert_to_float_triple(voxel_size)
    if margin is None:
        margin = 2 * max(voxel_size)
    margin = _convert_to_float_triple(margin)

    assert outer_radius > inner_radius > 0

    size = [
        int(math.ceil(2 * (outer_radius + ax_margin) / ax_voxel_size))
        for ax_margin, ax_voxel_size in zip(margin, voxel_size)
    ]

    classif_volume = aims.Volume(size[0], size[1], size[2], dtype="S16")
    classif_volume.setVoxelSize(voxel_size)
    emplace_cortex_sphere_classif(classif_volume,
                                  inner_radius,
                                  outer_radius,
                                  margin=margin,
                                  noise=noise,
                                  sigma=sigma)
    return classif_volume
Esempio n. 5
0
def aims_resample(src, ref):
    from soma import aims
    interp_dict = {"nn": 0, "lin": 1, "quad": 2}
    conv = aims.Converter(intype=src, outtype=aims.Volume('FLOAT'))
    src = conv(src)
    conv = aims.Converter(intype=ref, outtype=aims.Volume('FLOAT'))
    ref = conv(ref)

    # resampler
    resp = aims.ResamplerFactory_FLOAT().getResampler(interp_dict[interp])
    resp.setRef(src)  # volume to resample
    resp.setDefaultValue(0)  # set background to 0

    # resample
    voxel_size = np.array(ref.header()['voxel_size'])
    src2ref_trm = get_transformation(src, ref)
    output_ima = resp.doit(src2ref_trm, ref.getSizeX(), ref.getSizeY(), ref.getSizeZ(), voxel_size)
    output_ima.header()['referentials'] = ref.header()['referentials']
    output_ima.header()['transformations'] = ref.header()['transformations']
    return output_ima
Esempio n. 6
0
def _prepare_classif_for_VipHomotopic_Cortical(classif, filling_size):
    array_classif = np.asarray(classif)

    # Dilate the cortex by 1 voxel, otherwise the topologically spherical front
    # initialized by VipHomotopic (Cortical surface mode) is at the inside of
    # the border, which means that the final segmentation will be one voxel
    # off. The default -fclosing parameter prevents this from happening in
    # sulci by closing them, but it still happens at the top of gyri. Setting a
    # fake voxel size of 1 mm is a trick for expressing the dilation in terms
    # of voxels.
    #
    # The 1-voxel border is necessary for AimsMorpho{Dilation,Erosion}.
    aimsdata_classif = aims.Volume_S16(classif.getSize(), [1, 1, 1])
    aimsdata_classif[:] = classif[:]
    saved_voxel_size = classif.header()["voxel_size"][:3]
    aimsdata_classif.setVoxelSize(1, 1, 1)
    dilated = aimsalgo.AimsMorphoDilation(aimsdata_classif, 1)
    # Restore the voxel size in case the header is shared with the aims.Volume
    # that aimsdata_classif was created from (classif). BUG: restoring the
    # value like this is not thread-safe!
    aimsdata_classif.setVoxelSize(saved_voxel_size)
    del aimsdata_classif
    array_dilated = dilated.np

    tmp_classif = aims.Volume(classif)
    array_tmp_classif = np.asarray(tmp_classif)
    array_tmp_classif[np.logical_and(array_tmp_classif == CSF_LABEL,
                                     array_dilated != 0)] = CORTEX_LABEL
    del dilated, array_dilated

    # This almost-white region will serve as a first boundary in VipHomotopic,
    # before the final dilation towards the white matter. This helps restore
    # the continuity of the white matter so that the homotopic criterion
    # chooses the right connections (i.e. do not create spurious strands or
    # planes through the cortex).
    white = aims.Volume_S16(classif.gteSize(), [1, 1, 1])
    white[:] = classif[:]
    # Restore the header (in particular the voxel_size), which may not have
    # been copied in the constructor because a border is requested.
    white.header().update(classif.header())
    array_white = white.np
    array_white[array_white != WHITE_LABEL] = CSF_LABEL
    dilated_white = aimsalgo.AimsMorphoDilation(white, filling_size)
    del white, array_white
    array_dilated_white = dilated_white.np
    STEP1_FRONT_BARRIER = 199
    array_tmp_classif[array_dilated_white != 0] = STEP1_FRONT_BARRIER
    del dilated_white, array_dilated_white
    array_tmp_classif[array_classif == WHITE_LABEL] = WHITE_LABEL

    return tmp_classif
Esempio n. 7
0
def get_exchanged_propvol_files(classif_filename,
                                CSF_labels_on_white_filename,
                                white_labels_on_CSF_filename,
                                output_filename):
    classif = aims.read(classif_filename)
    CSF_labels_on_white = aims.read(CSF_labels_on_white_filename)
    white_labels_on_CSF = aims.read(white_labels_on_CSF_filename)
    output = aims.Volume(CSF_labels_on_white)

    np_CSF_labels_on_white = np.asarray(CSF_labels_on_white)
    np_white_labels_on_CSF = np.asarray(white_labels_on_CSF)
    np_classif = np.asarray(classif)
    np_output = np.asarray(output)

    white_mask = (np_classif == 150)
    CSF_mask = (np_classif == 50)

    np_output[white_mask] = np_CSF_labels_on_white[white_mask]
    np_output[CSF_mask] = np_white_labels_on_CSF[CSF_mask]

    temp_dir = None
    try:
        temp_dir = tempfile.mkdtemp(prefix="hcortex")
        temp_filename = os.path.join(temp_dir, 'raw_exchanged_labels.nii')
        aims.write(output, temp_filename)

        # These “failed components” will probably be separated by connexity
        # AimsReplaceLevel -i raw_exchanged_labels.nii.gz \
        # -o exchanged_labels.nii.gz \
        # -g 100000000 -n 0 -g 200000000 -n 0

        subprocess.check_call(["AimsConnectComp",
                               "-i", "raw_exchanged_labels.nii",
                               "-o", "connected_exchanged_labels.nii"],
                              cwd=temp_dir)

        # The background is cut in one big region + many small, restore it then
        # relabel
        propvol = aims.read(
            os.path.join(temp_dir, "connected_exchanged_labels.nii"))
    finally:
        if temp_dir:
            shutil.rmtree(temp_dir)
    np_propvol = np.asarray(propvol)
    exclusion_mask = (np_CSF_labels_on_white == -1)
    bulk_mask = (np_CSF_labels_on_white == 0)
    np_propvol[bulk_mask] = 0
    np_propvol[exclusion_mask] = -1

    relabel_positive_labels(propvol)
    aims.write(propvol, output_filename)
Esempio n. 8
0
def subject_labeling(gfile, dict_bck, translation, mask, vol_size, n_opal,
                     distmap_list, bck_list, proba_list, label_list,
                     patch_sizes):
    '''
    Label a subject sulcal graph (.arg file) for a specific pattern search using the SNIPE method
    '''
    print('Labeling %s' % gfile)
    distmap_list = [aims.Volume(d) for d in distmap_list]
    # Extract bucket
    fm = aims.FastMarching()
    if gfile not in dict_bck:
        graph = aims.read(gfile)
        side = gfile[gfile.rfind('/') + 1:gfile.rfind('/') + 2]
        data = extract_data(graph, flip=True if side == 'R' else False)
        sbck = data['bck2']
    else:
        sbck = dict_bck[gfile]
    sbck = np.array(sbck)
    sbck += translation
    sbck = np.asarray(apply_imask(sbck, mask))

    # Extract distmap
    fm = aims.FastMarching()
    vol = aims.Volume_S16(vol_size[0], vol_size[1], vol_size[2])
    vol.fill(0)
    for p in sbck:
        vol[p[0], p[1], p[2]] = 1
    sdistmap = fm.doit(vol, [0], [1])
    adistmap = np.asarray(sdistmap)
    adistmap[adistmap > pow(10, 10)] = 0

    # Compute classification
    grading_list = []
    for ps in patch_sizes:
        print('** PATCH SIZE %i' % ps)
        opm = OptimizedPatchMatch(patch_size=[ps, ps, ps],
                                  segmentation=False,
                                  k=n_opal)
        list_dfann = opm.run(distmap=sdistmap,
                             distmap_list=distmap_list,
                             bck_list=bck_list,
                             proba_list=proba_list)
        grading_list.append(grading(list_dfann, label_list))

    grade = np.nanmean(np.mean(grading_list, axis=0))
    ypred = 1 if grade > 0 else 0
    return ypred, grade
Esempio n. 9
0
def get_float_altitude(img, src_scl, dst_scl):
    def interpolate(rgb, src_scl, dst_scl):
        rgb = np.asarray(rgb).astype(float)
        #if rgb[1] < 10 or rgb[0] > 200:
        #if rgb[0] > 200:
        #rgb[0] = 0.
        #rgb[0] *= 2.
        #rgb[1] = 255.
        #rgb[2] = 255.
        dist = np.sum((dst_scl - rgb)**2, axis=1)
        #dist = ((dst_scl - rgb) ** 2)[:, 0]
        #print('dist:', dist)
        dmin = np.argmin(dist)
        if dmin == 0:
            ind = [dmin, dmin + 1]
        elif dmin == dst_scl.shape[0] - 1:
            ind = [dmin - 1, dmin]
        else:
            if dist[dmin - 1] < dist[dmin + 1]:
                ind = [dmin - 1, dmin]
            else:
                ind = [dmin, dmin + 1]
        # project
        axis = dst_scl[ind[1]] - dst_scl[ind[0]]
        d2 = np.sum(axis**2)
        if d2 == 0:
            return src_scl[-1]
        else:
            x = (rgb - dst_scl[ind[0]]).dot(axis) / d2
        if x < 0:
            x = 0.
        elif x > 1:
            x = 1.
        return src_scl[ind[0]] + (src_scl[ind[1]] - src_scl[ind[0]]) * x

    dst_scl = np.asarray(scl_map).astype(float)
    #dst_scl[:, 0] *= 2.
    #dst_scl[:, 1] = 255.
    new_img = aims.Volume(img.getSize(), dtype='FLOAT')
    new_img.header()['voxel_size'] = img.header()['voxel_size']
    for y in range(img.getSize()[1]):
        for x in range(img.getSize()[0]):
            rgb = img.at(x, y)
            alt = interpolate(rgb, src_scl, dst_scl)
            new_img.setValue(alt, x, y)
    return new_img
Esempio n. 10
0
def array_to_vol(array, header=None, dtype=np.float32):
    """Convert an numpy array into an aims Volume properly:
    header is updated taking into account array properties
    """
    new_arr = array.astype(dtype)
    arr = np.array(new_arr, order='F')
    vol = aims.Volume(arr)
    if header is not None:
        shape = list(new_arr.shape)
        index_max = len(shape)
        header['sizeX'] = shape[0]
        header['sizeY'] = shape[1]
        header['sizeZ'] = shape[2]
        if index_max == 3:
            header['sizeT'] = 1
        else:
            header['sizeT'] = shape[3]

        vol.header().update(header)
    return vol
Esempio n. 11
0
def relabel(labels):
    output = aims.Volume(labels)
    size_x = output.getSizeX()
    size_y = output.getSizeY()
    size_z = output.getSizeZ()
    old_to_new_labels = {}
    next_label = 1
    for z in range(size_z):
        for y in range(size_y):
            for x in range(size_x):
                label = labels.at(x, y, z)
                if label == 0:
                    new_label = 0
                else:
                    try:
                        new_label = old_to_new_labels[label]
                    except KeyError:
                        new_label = next_label
                        old_to_new_labels[label] = new_label
                        next_label += 1
                output.setValue(new_label, x, y, z)
    return output
Esempio n. 12
0
def randomize_labels(labels):
    import numpy as np
    np_input_labels = np.asarray(labels)
    max_label = np.max(np_input_labels)
    nonzero_labels = list(range(1, max_label + 1))
    random.shuffle(nonzero_labels)
    new_labels = [0] + nonzero_labels

    output = aims.Volume(labels)
    size_x = output.getSizeX()
    size_y = output.getSizeY()
    size_z = output.getSizeZ()
    for z in range(size_z):
        for y in range(size_y):
            for x in range(size_x):
                old_label = labels.at(x, y, z)
                if old_label >= 0:
                    new_label = new_labels[old_label]
                else:
                    new_label = 0
                output.setValue(new_label, x, y, z)
    return output
Esempio n. 13
0
def mesh_large_clusters(arr, clust_labeled, clust_sizes, labels,
                        output_clusters_large_mesh_filename, tempdir, ima,
                        thresh_size):
    large_clust_ima = aims.Volume(ima)
    large_clust_arr = np.asarray(large_clust_ima).squeeze()
    large_clust_arr[:] = 0
    for i in xrange(len(labels)):
        label = labels[i]
        if clust_sizes[i] > thresh_size:
            large_clust_arr[clust_labeled == label] = 1
    large_clust_ima_filename = os.path.join(tempdir, "large_clusters.nii")
    writer = aims.Writer()
    writer.write(large_clust_ima, large_clust_ima_filename)
    large_clust_graph_filename = os.path.join(tempdir, "large_clusters.arg")
    cmd = 'AimsClusterArg --input %s --output %s' % \
    (large_clust_ima_filename, large_clust_graph_filename)
    print "\n============="
    print cmd
    print "============="
    os.popen(cmd)
    graph = aims.read(large_clust_graph_filename)
    print "-----"
    large_clust_meshs = None
    for v in graph.vertices():
        if large_clust_meshs is None:
            large_clust_meshs = v['aims_Tmtktri']
        else:
            aims.SurfaceManip.meshMerge(large_clust_meshs, v['aims_Tmtktri'])
    if large_clust_meshs is not None:
        large_clust_meshs.header()['referentials'] = ima.header(
        )['referentials']
        large_clust_meshs.header()['transformations'] = ima.header(
        )['transformations']
        writer.write(large_clust_meshs, output_clusters_large_mesh_filename)
        return large_clust_meshs
    else:
        print "No large cluster generated"
        return None
Esempio n. 14
0
def resample(input_image, transformation, output_vs=None, background=0,
             values=None):
    """
        Transform and resample a volume that as discret values

        Parameters
        ----------
        input_image: file
            Path to the input volume (.nii or .nii.gz file)
        transformation: file
            Linear transformation file (.trm file)
        output_vs: tuple
            Output voxel size (default: None, no resampling)
        background: int
            Background value (default: 0)
        values: []
            Array of unique values ordered by descendent priority. If not given,
            priority is set by ascendent values

        Return
        ------
        resampled_vol:
            Transformed and resampled volume
    """
    # Read inputs
    vol = aims.read(input_image)
    vol_dt = vol.__array__()

    if transformation:
        trm = aims.read(transformation)
    else:
        trm = aims.AffineTransformation3d(np.eye(4))
    inv_trm = trm.inverse()

    if output_vs:
        output_vs = np.array(output_vs)
        
        # New volume dimensions
        resampling_ratio = np.array(vol.header()['voxel_size'][:3]) / output_vs
        orig_dim = vol.header()['volume_dimension'][:3]
        new_dim = list((resampling_ratio * orig_dim).astype(int))
    else:
        output_vs = vol.header()['voxel_size'][:3]
        new_dim = vol.header()['volume_dimension'][:3]

    # Transform the background
    # Using the inverse is more straightforward and supports non-linear
    # transforms
    resampled = aims.Volume(new_dim, dtype=vol_dt.dtype)
    resampled.header()['voxel_size'] = output_vs
    # 0 order (nearest neightbours) resampling
    resampler = aimsalgo.ResamplerFactory(vol).getResampler(0)
    resampler.setDefaultValue(background)
    resampler.setRef(vol)
    resampler.resample_inv(vol, inv_trm, 0, resampled)
    resampled_dt = np.asarray(resampled)

    if values is None:
        values = sorted(np.unique(vol_dt[vol_dt != background]))
    else:
        # Reverse order as value are passed by descendent priority
        values = values[::-1]

    # Create one bucket by value (except background)
    # FIXME: Create several buckets because I didn't understood how to add
    #  several bucket to a BucketMap
    for i, v in enumerate(values):
        bck = aims.BucketMap_VOID()
        bck.setSizeXYZT(*vol.header()['voxel_size'][:3], 1.)
        bk0 = bck[0]
        for p in np.vstack(np.where(vol_dt == v)[:3]).T:
            bk0[list(p)] = v

        bck2 = aimsalgo.resampleBucket(bck, trm, inv_trm, output_vs)

        # FIXME: Could not assign the correct value with the converter.
        # Using the converter, the new_dim must incremented
        # conv = aims.Converter(intype=bck2, outtype=aims.AimsData(vol))
        # conv.convert(bck2, resampled)
        # Use a for loop instead:
        for p in bck2[0].keys():
            c = p.list()
            if c[0] < new_dim[0] and c[1] < new_dim[1] and c[2] < new_dim[2]:
                resampled_dt[c[0], c[1], c[2]] = values[i]

    return resampled
Esempio n. 15
0
def _make_similar_volume(data_array, ref):
    volume = aims.Volume(data_array)
    volume.header().update(ref.header())
    return volume
Esempio n. 16
0
def _make_similar_volume(data_array, ref):
    volume = aims.Volume(data_array)
    volume.copyHeaderFrom(ref.header())
    return volume
Esempio n. 17
0
    if thresh_norm_ratio < 1:
        arr, thres = array_utils.arr_threshold_from_norm2_ratio(
            arr, thresh_norm_ratio)
        print "Threshold image as %f" % thres
    clust_bool = np.zeros(arr.shape, dtype=bool)
    #((arr > thresh_neg_low) & (arr < thresh_neg_high) | (arr > thresh_pos_low) & (arr < thresh_pos_high)).sum()
    clust_bool[((arr > thresh_neg_low) & (arr < thresh_neg_high)) |
               ((arr > thresh_pos_low) & (arr < thresh_pos_high))] = True
    arr[np.logical_not(clust_bool)] = False
    clust_labeled, n_clusts = scipy.ndimage.label(clust_bool)
    clust_sizes = scipy.ndimage.measurements.histogram(clust_labeled, 1,
                                                       n_clusts, n_clusts)
    labels = np.unique(clust_labeled)[1:]
    centers = scipy.ndimage.center_of_mass(clust_bool, clust_labeled, labels)
    # _clusters.nii.gz
    clusters_values_ima = aims.Volume(ima)
    clusters_values_ima_arr = np.asarray(clusters_values_ima).squeeze()
    #clusters_values_ima_arr[clust_bool] = arr[clust_bool]
    clusters_values_ima_arr[::] = arr[::]
    writer = aims.Writer()
    writer.write(clusters_values_ima, output_clusters_values_filename)
    # _clusters_labels.nii.gz
    clusters_labels_ima = aims.Volume(ima)
    clusters_labels_ima_arr = np.asarray(clusters_labels_ima).squeeze()
    clusters_labels_ima_arr[:] = clust_labeled[:]
    writer.write(clusters_labels_ima, output_clusters_labels_filename)

    ##########################################################################
    # Get clusters information
    header_info, info = clusters_info(arr, clust_labeled, clust_sizes, labels,
                                      centers, trm_xyz_to_mm, atlas_cort,