示例#1
0
def draw_ellipsoid(shape, radius, center, FWHM, noise=0):
    sigma = FWHM / 2.35482
    cutoff = 2 * FWHM

    # draw a sphere
    R = max(radius)
    zoom_factor = np.array(radius) / R
    size = int((R + cutoff)*2)
    c = size // 2
    z, y, x = np.meshgrid(*([np.arange(size)] * 3), indexing='ij')
    h = np.sqrt((z - c)**2+(y - c)**2+(x - c)**2) - R
    mask = np.abs(h) < cutoff
    im = np.zeros((size,)*3, dtype=np.float)
    im[mask] += np.exp((h[mask] / sigma)**2/-2)/(sigma*np.sqrt(2*np.pi))

    # zoom so that radii are ok
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        im = zoom(im, zoom_factor)

    # shift and make correct shape
    center_diff = center - np.array(center_of_mass(im))
    left_padding = np.round(center_diff).astype(np.int)
    subpx_shift = center_diff - left_padding

    im = shift(im, subpx_shift)
    im = crop_pad(im, -left_padding, shape)
    im[im < 0] = 0

    assert_almost_equal(center_of_mass(im), center, decimal=2)

    if noise > 0:
        im += np.random.random(shape) * noise * im.max()

    return (im / im.max() * 255).astype(np.uint8)
示例#2
0
def evaluate_bioid(loss, load_batch, n_batches):
    from scipy.ndimage.measurements import center_of_mass, maximum_position
    from numpy.linalg import norm
    L = []
    for batch in xrange(n_batches()):
        load_batch(batch)
        output = loss.get_sink("output")
        out = output.evaluate().np
        target = loss.get_parameter("target")
        tch = target.data.np

        out = np.rollaxis(out, 3)

        for i in xrange(out.shape[0]):
            o0, o1 = out[i].reshape(2, 30, 30)
            t0, t1 = tch[i].reshape(2, 30, 30)
            mo0 = np.array(maximum_position(o0))
            mo1 = np.array(maximum_position(o1))
            mt0 = np.array(center_of_mass(t0))
            mt1 = np.array(center_of_mass(t1))
            mask0 = np.zeros_like(o0)
            mask1 = np.zeros_like(o1)
            region0 = np.clip((mo0 - 2, mo0 + 3), 0, 30)
            region1 = np.clip((mo1 - 2, mo1 + 3), 0, 30)
            mask0[region0[0, 0]:region0[1, 0], region0[0, 1]:region0[1, 1]] = 1
            mask1[region1[0, 0]:region1[1, 0], region1[0, 1]:region1[1, 1]] = 1
            mo0 = center_of_mass(o0, mask0)
            mo1 = center_of_mass(o1, mask1)
            dst = max(norm(mo0 - mt0),
                      norm(mo1 - mt1)) / norm(mt0 - mt1)
            L.append(dst)
    L = np.array(L)
    print "n =", len(L)
    print "Average normalized distance: ", L.mean()
    print "Correct: ", np.sum(L < 0.25) / float(len(L))
示例#3
0
def center_of_blob(img):
    if type(img) is list:
        centers = []
        for blob in img:
            center = np.array([center_of_mass(blob)[i] for i in range(2)])
            centers.append(center)
        return centers
    else:
        center = np.array([center_of_mass(img)[i] for i in range(2)])
        return center
def process_eso(vol_out):
    print 'iterpolating eso...'
    voleso=vol_out==1
    voleso=voleso.astype(np.uint8)
    idxesoini=np.where(voleso>0)
    
    id_eso=np.where(vol_out==1)
    seg_eso=np.zeros_like(vol_out)
    seg_eso[id_eso]=1
    listorgan=np.where(seg_eso>0)
    zmin=np.min(listorgan[0])
    zmax=np.max(listorgan[0])
    ini_found=False
    for idx in xrange(zmin,zmax):
        eso_slice=seg_eso[idx]
        centroid=center_of_mass(eso_slice)
        if not ini_found:#if we have not found the first slice empty
            if np.isnan(centroid).any():#look for the first emppty slice
                #print 'is NAN ',idx
                ini=idx-1
                pini=list(center_of_mass(seg_eso[idx-1]))
                pini.append(idx-1)
                ini_found=True
        else:#if we have already found the first empty slice, look for the final one
            idvox=np.where(eso_slice==1)
            nvoxels=len(idvox[0])
            if not np.isnan(centroid).any() and nvoxels>5:#the slice with data and enough voxels

                #print 'final nan ',idx
                fin=idx
                pfin=list(center_of_mass(seg_eso[fin]))
                pfin.append(idx)
                #print 'pini ',pini
                #print 'pfin ',pfin
                for z in xrange(ini,fin):#we will fill the empty slices here
                    newcenter=interpolateline(pini,pfin,z)
                    #print 'new center ',newcenter
                    #print 'prev center ',center_of_mass(seg_eso[z-1])
                    translation=np.int16(np.array(newcenter)-np.array(center_of_mass(seg_eso[z-1])))
                    #print 'trans ',translation
                    #tx = tf.SimilarityTransform(translation=(0,0))#tuple(translation)
                    if z==ini:
                        slicetmp = shift(seg_eso[z-5],translation)#tf.warp(seg_eso[z-1], tx)
                    else:
                        slicetmp = shift(seg_eso[z-1],translation)#tf.warp(seg_eso[z-1], tx)
                    #print 'unique slice befor trans ',np.unique(seg_eso[z-1])
                    #print 'unique slice tmp ',np.unique(slicetmp)
                    seg_eso[z]=slicetmp
                ini_found=False
    idxeso=np.where(seg_eso>0)
    volfinal=np.copy(vol_out)
    volfinal[idxesoini]=0
    volfinal[idxeso]=1
    return volfinal
示例#5
0
    def find_phan_centers(self,params):
        """
        Find the center of the phantom for the slices of analysis
        :return:
        """

        self.slices_of_interest =  ptg.find_slices_of_interest(self.images,params)
        print('haleluja!',self.slices_of_interest)
        for key in self.slices_of_interest:
        
            print ("curr SOI",key)
            #plt.imshow(self.images[self.slices_of_interest[key],:,:])
            #plt.title("%s"%key)
            #plt.show()

            SOI = self.images[self.slices_of_interest[key],:,:]
            SOI = np.where(SOI > np.percentile(SOI,48), 1, 0)  #  convert slice to binary based on threshold
            #SOI = morph.binary_fill_holes(SOI)  # fill in air pockets to make one solid ROI
            SOI_labeled, no_roi = meas.label(SOI)  # identify the ROIs
            if no_roi < 1 or no_roi is None:
                raise ValueError, "Unable to locate the CatPhan"
            hist,bins = np.histogram(SOI_labeled,bins=no_roi) # hist will give the size of each label
            SOI = np.where(SOI_labeled == np.argmax(hist), 1, 0)  # remove all ROIs except the largest one (the CatPhan)
            self.slice_centers[key] = meas.center_of_mass(SOI)
            self.SOI_cleaned[key] = SOI
示例#6
0
def measure_barycenter(vignet, pixscale=1.):
    x,y = center_of_mass(vignet)
    x -= (vignet.shape[0]-1)/2
    x *= pixscale
    y -= (vignet.shape[1]-1)/2
    y *= pixscale    
    return (x,y)
示例#7
0
    def find_roll(self):
        """
        Determine the roll of the phantom based on the phantom air bubbles on the HU slice.
        :return:
        """
        SOI = self.SOI_cleaned['HU']
        invSOI = ptg.invert(SOI)
        labels, no_roi = meas.label(invSOI)
        roi_sizes = [meas.sum(invSOI, labels, index=item) for item in range(1,no_roi+1)]
        air_bubbles = [idx+1 for idx, item in enumerate(roi_sizes) if item < np.median(roi_sizes)*1.5 and item > np.median(roi_sizes)*(1/1.5)]
        if len(air_bubbles) != 2:
            self.phan_roll = 0

            #raise RuntimeWarning, "Roll unable to be determined; assuming 0"
        else:
            air_bubble_CofM = meas.center_of_mass(invSOI, labels, air_bubbles)
            y_dist = air_bubble_CofM[0][0] - air_bubble_CofM[1][0]
            x_dist = air_bubble_CofM[0][1] - air_bubble_CofM[1][1]
            angle = np.arctan2(y_dist, x_dist) * 180/np.pi
            if angle < 0:
                roll = abs(angle) - 90
            else:
                roll = angle - 90
            self.phan_roll = roll

            self._roll_found = True
示例#8
0
def fit_ellipse(img, full_output=False):

    img = np.array(img, dtype=float)

    center = center_of_mass(img)
    r = 10.
    
    x = np.arange(0., float(img.shape[1]), 1.)
    y = np.arange(0., float(img.shape[0]), 1.)
    X,Y = np.meshgrid(x, y)    

    def fminfunc(vals):
        #center = [vals[0], vals[1]]
        a,b,angle = vals
        Z = ellipse(X, Y, center, a, b, angle)
        err = np.abs(img-Z)
        errsum = np.sum(err)
        #print errsum
        return errsum
    
    a = 20
    b = 20
    angle = np.pi/4
    vals = [a,b,angle]
    tmp = scipy.optimize.fmin( fminfunc, vals, full_output = 1, disp=0)
    vals = tmp[0]
    #center = [vals[0], vals[1]]
    a,b,angle = vals
    
     
    if full_output is False:
        return center, a, b, angle
    else:
        Z = ellipse(X, Y, center, a, b, angle)
        return center, a, b, angle, Z
示例#9
0
def align_image_on_cores_com(img, bg):
    finder_conf = wds.FinderConfiguration()
    finder_conf.set("max_scale", 2)
    finder_conf.set("min_scale", 1)
    finder_conf.set("interscales", False)

    group = wds.FeaturesFinder(img, bg, finder_conf).execute()[0]

    cmp_intensity = lambda x, y: cmp(x.get_intensity(), y.get_intensity())
    brightest = group.sorted_list(cmp=cmp_intensity)[-1]

    cores = wfeatures.FeaturesGroup()
    # consider only features with total intensity > 10% of brightest one.
    for feature in group.get_features():
        if feature.get_total_intensity() > 0.1 * brightest.get_total_intensity():
            cores.add_feature(feature)

    img_cores = np.zeros_like(group.get_img().data)
    for core in cores:
        img_cores += core.get_segment_image()

    com = measurements.center_of_mass(img_cores)

    print "COM:", com
    return com
示例#10
0
def get_coord_centroid(filename, region):
    """
    Get centroid coordinates from an image and a region
    filename: fits file
    region: ds9 region
    """
    import astropy.io.fits as pyfits
    import astropy.wcs as pywcs
    import pyregion
    from scipy.ndimage.measurements import center_of_mass

    fits = pyfits.open(filename)
    header, data = flatten(fits)

    # extract mask and find center of mass
    r = pyregion.open(region)
    mask = r.get_mask(header=header, shape=data.shape)
    dec_pix, ra_pix = center_of_mass(mask)
    
    # convert to ra/dec in angle
    w = pywcs.WCS(fits[0].header)
    #w = w.celestial # needs newer astropy
    ra, dec = w.all_pix2world(ra_pix, dec_pix, 0, 0, 0, ra_dec_order=True)

    fits.close()
    return float(ra), float(dec)
def calculateTestedClass(testedimg, classId):
    #img = Image.open(imgfile);
    img = testedimg
    npimg = np.array(img, dtype=np.uint8);
    
    filtereddataclasses = npimg
    
    #make sure to keep only needed class
    filtereddataclasses[npimg != classId] = 0
    
    #find all connected components    
    #smooth the image to remove small objects?
    blurradius = 0.5
    #threshold = 0
    
    if useSmoothed == 1:
        smoothedimg = ndimage.gaussian_filter(filtereddataclasses, blurradius)
    else:
        smoothedimg = filtereddataclasses
    
    
    labeled, nr_objects = ndimage.label(smoothedimg > 0)
    
    print 'Number of items (classid: ' + str(classId) + ') detected: ' + str(nr_objects)
    
    centreobjects = center_of_mass(labeled, labels=labeled, index=range(1, nr_objects+1))
    
    return centreobjects  # for each item, the format is y, x
    def extract_sagital_slice(self):
        """Extract the sagital slice where the detection is done.

        If the segmentation is provided,
            the 2D sagital slice is choosen accoding to the segmentation.

        If the segmentation is not provided,
            the 2D sagital slice is choosen as the mid-sagital slice of the input image.
        """

        if self.fname_seg is not None:
            img_seg = Image(self.fname_seg)

            z_mid_slice = img_seg.data[:, int(img_seg.dim[1] / 2), :]
            if 1 in z_mid_slice:  # if SC segmentation available at this slice
                self.rl_coord = int(center_of_mass(z_mid_slice)[1])  # Right_left coordinate
            else:
                self.rl_coord = int(img_seg.dim[2] / 2)
            del img_seg

        else:
            img = Image(self.fname_im)
            self.rl_coord = int(img.dim[2] / 2)  # Right_left coordinate
            del img

        sct.run(['sct_crop_image', '-i', self.fname_im, '-start', str(self.rl_coord), '-end', str(self.rl_coord), '-dim', '2', '-o', self.slice2D_im])
示例#13
0
def segment_2d(model_fname, contrast_type, input_size, im_in):
    """Segment data using 2D convolutions."""
    seg_model = nn_architecture_seg(height=input_size[0],
                                    width=input_size[1],
                                    depth=2 if contrast_type != 't2' else 3,
                                    features=32,
                                    batchnorm=False,
                                    dropout=0.0)
    seg_model.load_weights(model_fname)

    seg_crop = zeros_like(im_in, dtype=np.uint8)

    data_norm = im_in.data
    x_cOm, y_cOm = None, None
    for zz in range(im_in.dim[2]):
        pred_seg = seg_model.predict(np.expand_dims(np.expand_dims(data_norm[:, :, zz], -1), 0),
                                     batch_size=BATCH_SIZE)[0, :, :, 0]
        pred_seg_th = (pred_seg > 0.5).astype(int)
        pred_seg_pp = post_processing_slice_wise(pred_seg_th, x_cOm, y_cOm)
        seg_crop.data[:, :, zz] = pred_seg_pp

        if 1 in pred_seg_pp:
            x_cOm, y_cOm = center_of_mass(pred_seg_pp)
            x_cOm, y_cOm = np.round(x_cOm), np.round(y_cOm)

    return seg_crop.data
示例#14
0
def crop_image_around_centerline(im_in, ctr_in, crop_size):
    """Crop the input image around the input centerline file."""
    data_ctr = ctr_in.data
    data_ctr = data_ctr if len(data_ctr.shape) >= 3 else np.expand_dims(data_ctr, 2)
    data_in = im_in.data.astype(np.float32)
    im_new = empty_like(im_in)  # but in fact we're going to crop it

    x_lst, y_lst, z_lst = [], [], []
    data_im_new = np.zeros((crop_size, crop_size, im_in.dim[2]))
    for zz in range(im_in.dim[2]):
        if np.any(np.array(data_ctr[:, :, zz])):
            x_ctr, y_ctr = center_of_mass(np.array(data_ctr[:, :, zz]))

            x_start, x_end = _find_crop_start_end(x_ctr, crop_size, im_in.dim[0])
            y_start, y_end = _find_crop_start_end(y_ctr, crop_size, im_in.dim[1])

            crop_im = np.zeros((crop_size, crop_size))
            x_shape, y_shape = data_in[x_start:x_end, y_start:y_end, zz].shape
            crop_im[:x_shape, :y_shape] = data_in[x_start:x_end, y_start:y_end, zz]

            data_im_new[:, :, zz] = crop_im

            x_lst.append(str(x_start))
            y_lst.append(str(y_start))
            z_lst.append(zz)

    im_new.data = data_im_new
    return x_lst, y_lst, z_lst, im_new
示例#15
0
def find_sudoku_edges(im, axis=0):
    """ 寻找对齐后数独图像的的单元边线 """
    # threshold and sum rows and columns
    #阈值化,像素值小于128的阈值处理后为1,大于128的为0
    trim = 1*(128 > im)
    #阈值处理后对行(列)相加求和
    s = trim.sum(axis=axis)
    print s
    # find center of strongest lines
    # 寻找连通区域
    s_labels, s_nbr = measurements.label((0.5*max(s)) < s)
    print s_labels
    print s_nbr
    #计算各连通域的质心
    m = measurements.center_of_mass(s, s_labels, range(1, s_nbr+1))
    print m
    #对质心取整,质心即为粗线条所在位置
    x = [int(x[0]) for x in m]
    print x
	# if only the strong lines are detected add lines in between
    # 如果检测到了粗线条,便在粗线条间添加直线
    if 4 == len(x):
        dx = diff(x)
        x = [x[0], x[0]+dx[0]/3, x[0]+2*dx[0]/3, x[1], x[1]+dx[1]/3, x[1]+2*dx[1]/3, x[2], x[2]+dx[2]/3, x[2]+2*dx[2]/3, x[3]]
    if 10 == len(x):
        return x
    else:
        raise RuntimeError('Edges not detected.')
示例#16
0
文件: lineest.py 项目: beanyh/yeobaek
def vertical_stddev(image):
    """Compute the standard deviation in the vertical direction.
    This is used below to get a rough idea of how large characters
    and lines are."""
    assert amax(image)>amin(image)
    cy,cx = measurements.center_of_mass(1.0*image)
    return (sum(((arange(len(image))-cy)[:,newaxis]*image)**2)/sum(image))**.5,cy,cx
示例#17
0
def fit_circle(img):

    center = center_of_mass(img)
    r = 10
    
    x = np.arange(0, img.shape[0], 1)
    y = np.arange(0, img.shape[1], 1)
    X,Y = np.meshgrid(x, y)    

    def circle(x,y, center, r):
        R = np.sqrt((X-center[1])**2 + (Y-center[0])**2)
        Z = R<r
        Z *= 255
        return Z

    def fminfunc(vals):
        #center = [vals[0], vals[1]]
        r = vals[0]
        Z = circle(X, Y, center, r)
        err = np.abs(img-Z)
        errsum = np.sum(err)
        #print errsum
        return errsum
    
    vals = [r]
    tmp = scipy.optimize.fmin( fminfunc, vals, full_output = 1, disp=0)
    vals = tmp[0]
    #center = [vals[0], vals[1]]
    r = vals[0]
    Z = circle(X, Y, center, r)
    
    return center, r, Z
示例#18
0
def locate(characters): 
    #find the "center of mass" of the array

    for char in characters:
        image = invert_image(char.image)
        char.center = center_of_mass(image)

    return characters
示例#19
0
文件: wds.py 项目: flomertens/wise
 def get_center_of_shape(self, segment):
     if self.center_of_shape is None:
         labels = self.get_labels()
         # ids = self.get_segmentids()
         ids = np.unique(labels)
         coss = measurements.center_of_mass(labels, labels, ids)
         self.center_of_shape = dict(zip(ids, np.array(coss)))
     return self.center_of_shape.get(segment.get_segmentid(), segment.get_coord(mode="lm"))
示例#20
0
def find_center_by_scattering_lobes(image, threshold=15):
    '''find center of mass of stripe domain lattice scattering lobes in the
    upper left and lower right quadrant of the image and
    use these to calculate center of scattering pattern'''
    limit_x, limit_y = [i // 4 for i in image.shape]
    quad = median_filter(image[:limit_x, :limit_y], size=6, mode='constant')
    mean = quad.mean()
    std = quad.std()
    lobe1 = np.array(center_of_mass(quad * quad > (mean + threshold * std)))
    limit_x, limit_y = [i - i // 4 for i in image.shape]
    quad = median_filter(image[limit_x:, limit_y:], size=6, mode='constant')
    mean = quad.mean()
    std = quad.std()
    lobe2 = np.array(center_of_mass(quad * quad > (mean + threshold * std)))
    lobe2 += [limit_x, limit_y]
    center = np.array(lobe1 + (lobe2 - lobe1) / 2, dtype=np.int)
    return center
示例#21
0
def get_contours3d(A, dims, thr=0.9):
    """Gets contour of spatial components and returns their coordinates

     Parameters
     -----------
     A:   np.ndarray or sparse matrix
               Matrix of Spatial components (d x K)
     dims: tuple of ints
               Spatial dimensions of movie (x, y, z)
     thr: scalar between 0 and 1
               Energy threshold for computing contours (default 0.995)

     Returns
     --------
     Coor: list of coordinates with center of mass and
            contour plot coordinates (per layer) for each component
    """
    d, nr = np.shape(A)
    d1, d2, d3 = dims
    x, y = np.mgrid[0:d2:1, 0:d3:1]

    coordinates = []
    cm = np.asarray([center_of_mass(a.reshape(dims, order='F')) for a in A.T])
    for i in range(nr):
        pars = dict()
        indx = np.argsort(A[:, i], axis=None)[::-1]
        cumEn = np.cumsum(A[:, i].flatten()[indx]**2)
        cumEn /= cumEn[-1]
        Bvec = np.zeros(d)
        Bvec[indx] = cumEn
        Bmat = np.reshape(Bvec, dims, order='F')
        pars['coordinates'] = []
        for B in Bmat:
            cs = pl.contour(y, x, B, [thr])
            # this fix is necessary for having disjoint figures and borders plotted correctly
            p = cs.collections[0].get_paths()
            v = np.atleast_2d([np.nan, np.nan])
            for pths in p:
                vtx = pths.vertices
                num_close_coords = np.sum(np.isclose(vtx[0, :], vtx[-1, :]))
                if num_close_coords < 2:
                    if num_close_coords == 0:
                        # case angle
                        newpt = np.round(old_div(vtx[-1, :], [d2, d1])) * [d2, d1]
                        vtx = np.concatenate((vtx, newpt[np.newaxis, :]), axis=0)

                    else:
                        # case one is border
                        vtx = np.concatenate((vtx, vtx[0, np.newaxis]), axis=0)

                v = np.concatenate((v, vtx, np.atleast_2d([np.nan, np.nan])), axis=0)

            pars['coordinates'] += [v]
        pars['CoM'] = np.squeeze(cm[i, :])
        pars['neuron_id'] = i + 1
        coordinates.append(pars)
    return coordinates
示例#22
0
文件: wds.py 项目: flomertens/wise
 def get_center_of_mass(self, segment):
     if self.center_of_mass is None:
         labels = self.get_labels()
         img = self.get_img()
         # ids = self.get_segmentids()
         ids = np.unique(labels)
         coms = measurements.center_of_mass(img.data, labels, ids)
         self.center_of_mass = dict(zip(ids, np.array(coms)))
     return self.center_of_mass.get(segment.get_segmentid(), segment.get_coord(mode="lm"))
示例#23
0
def start_point(area, bkg):
    ''' Returns a guess of fitting parameters to be used as the starting point
    of the fitting process.'''
    center = area.shape[0] // 2
    area_bkg = area - bkg
    A = 1.54 * area_bkg[center, center]
    x0, y0 = center_of_mass(area_bkg)

    return [A, x0, y0, np.mean(bkg)]
示例#24
0
    def find_GEO(self):
        """
        Determine the geometric distortion. Averages 3 slices around HU slice.
        :return:
        """

        # average 3 slices around the nominal slice

        GEO_slice = np.mean(self.images[
self.slices_of_interest['HU'] - 1:self.slices_of_interest['HU'] + 1,
small_FOV_settings['GEO_box_bounds'][0]:small_FOV_settings['GEO_box_bounds'][2],
small_FOV_settings['GEO_box_bounds'][1]:small_FOV_settings['GEO_box_bounds'][3]], 0)

        
        #plt.imshow(GEO_slice)

        # construct black & white image
        GEO_bw1 = np.where(GEO_slice > np.median(GEO_slice) * 1.3, 1, 0)
        GEO_bw2 = np.where(GEO_slice < np.median(GEO_slice) * 0.7, 1, 0)
        GEO_bw = GEO_bw1 + GEO_bw2

        plt.imshow(GEO_bw)
        plt.title("GEO_slice")
        #plt.show()

        # find centers of geometric points
        labels, no_roi = meas.label(GEO_bw)
        print (no_roi)

        #if no_roi != 4:
        #    raise ValueError, "Unable to locate the geometric nodes. May need to adjust the geometric ROI slice. "


        geo_CofM = meas.center_of_mass(GEO_bw, labels, index=[1,2,3,4])

        self.geo_CofM = geo_CofM

        # distance calculations (result is in mm; nominal distance is 50mm (5cm)
        self.results['v1'] = ptg.dist_2points(geo_CofM[0], geo_CofM[1]) * self.improps['mm/Pixel']
        self.results_diffs['v1'] = self.results['v1'] - nominal_GEO
        self.results['h1'] = ptg.dist_2points(geo_CofM[0], geo_CofM[2]) * self.improps['mm/Pixel']
        self.results_diffs['h1'] = self.results['h1'] - nominal_GEO
        self.results['v2'] = ptg.dist_2points(geo_CofM[3], geo_CofM[1]) * self.improps['mm/Pixel']
        self.results_diffs['v2'] = self.results['v2'] - nominal_GEO
        self.results['h2'] = ptg.dist_2points(geo_CofM[3], geo_CofM[2]) * self.improps['mm/Pixel']
        self.results_diffs['h2'] = self.results['h2'] - nominal_GEO

        res_diffs = np.array((self.results_diffs['v1'], self.results_diffs['h1'], self.results_diffs['v2'],
                     self.results_diffs['h2']))

        if all(res_diffs < tolerances['GEO']) and all(res_diffs > -tolerances['GEO']):
            self.GEO_pass = True
        else:
            self.GEO_pass = False

        pass
示例#25
0
def fix_orientation(data):
    from scipy.ndimage.measurements import center_of_mass
    # Find the first and last frame with nonzero measurement_data (from z)
    x, y, z = np.nonzero(data)
    # For some reason I was loading the file in such a way that it wasn't sorted
    z = sorted(z)
    start, end = z[0], z[-1]
    # Get the COP for those two frames
    start_x, start_y = center_of_mass(data[:, :, start])
    end_x, end_y = center_of_mass(data[:, :, end])
    # We've calculated the start and end point of the measurement (if at all)
    x_distance = end_x - start_x
    # If this distance is negative, the subject walked right to left
    #print .The distance between the start and end is: {}".format(x_distance)
    if x_distance < 0:
        # So we flip the measurement_data around
        data = np.rot90(np.rot90(data))
        #measurement_data = measurement_data[::-1,::-1,:]  #Alternative
    return data
示例#26
0
def gen_feature_mfcc(x):
	v, asp = x
	try:
		if np.isnan(v).any() or np.isinf(v).any():
			raise Exception('MFCC contains Nan of Inf')
		xn, (xmin, xmax), xmean, xvar, xskew, xkurt =  stats.describe(v)
		d = np.diff(v, 1, 0)
		dmean = np.mean(d, 0)
		feat = np.reshape((measurements.center_of_mass(v)[0],
			measurements.center_of_mass(asp)[0], measurements.maximum_position(asp)[0]),(3,))
		hist = 1.0*measurements.histogram(asp, 0, 1, 4) / asp.shape[0]/asp.shape[1]
		x = np.concatenate((xmean,xmin,xmax,xvar,dmean,feat,hist[-1:]))
		if np.isnan(x).any() or np.isinf(x).any():
			raise Exception('Feature vector contains Nan of Inf')
	except:
		#print d, dd
		print xmin.shape
		raise
	return x.T
示例#27
0
文件: misc.py 项目: B-Rich/nipype
    def _eucl_cog(self, nii1, nii2):
        origdata1 = nii1.get_data().astype(np.bool)
        cog_t = np.array(center_of_mass(origdata1)).reshape(-1, 1)
        cog_t = np.vstack((cog_t, np.array([1])))
        cog_t_coor = np.dot(nii1.get_affine(), cog_t)[:3, :]

        origdata2 = nii2.get_data().astype(np.bool)
        (labeled_data, n_labels) = label(origdata2)

        cogs = np.ones((4, n_labels))

        for i in range(n_labels):
            cogs[:3, i] = np.array(center_of_mass(origdata2, labeled_data, i + 1))

        cogs_coor = np.dot(nii2.get_affine(), cogs)[:3, :]

        dist_matrix = cdist(cog_t_coor.T, cogs_coor.T)

        return np.mean(dist_matrix)
示例#28
0
def calc_object_pos(movie):

    # define background, do background subtraction and thresholding
    background = nim.darken(movie.frames[0].raw, movie.frames[-1].raw)
    for i, frame in enumerate(movie.frames):

        print 'processing frames... ', i

        movie.frames[i].absdiff = nim.absdiff(frame.raw, background)
        movie.frames[i].diffthresh = nim.threshold(movie.frames[i].absdiff, THRESH_HOLD)
        
        ## TODO: right now this assumes the thresholding is perfect...!
        # find center of fly:
        center = center_of_mass(movie.frames[i].diffthresh)
        
        if 1:
            
            if center[0] == np.nan:
                center = (0,0)
            
            limlo_x = center[0]-ROI_RADIUS
            if limlo_x < 0:
                limlo_x = 0
            limhi_x = center[0]+ROI_RADIUS
            if limhi_x > movie.height:
                limhi_x = movie.height
                
            limlo_y = center[1]-ROI_RADIUS
            if limlo_y < 0:
                limlo_y = 0
            limhi_y = center[1]+ROI_RADIUS
            if limhi_y > movie.width:
                limhi_y = movie.width
                
            # TODO: right now object entering or leaving frame doesnt work perfectly
            uimg = movie.frames[i].diffthresh[limlo_x:limhi_x, limlo_y:limhi_y]
            movie.frames[i].uimg = uimg
            movie.frames[i].uimg_center = center
            
            el = nim.fit_ellipse(uimg)
            center_relative_to_roi,xr,yr,theta_to_xaxis = el
            
            tmp = np.array([float(ROI_RADIUS)/2, float(ROI_RADIUS)/2])
            obj_pos = np.array(center) + np.array(center_relative_to_roi) - tmp
            
            if xr>=yr:
                angle = theta_to_xaxis
            else:
                angle = theta_to_xaxis+np.pi/2.
            
            movie.frames[i].obj = Object(obj_pos, angle)
            
            print xr,yr

    return movie        
示例#29
0
def findCenter(frame, threshold):    
    '''Take a frame, and find the pupil center'''
    img = frame[...,0]
    h,w = img.shape
    
    # Threshold the image and adapt - if necessary - the threshold
    (bw, threshold) = adaptThreshold(img, threshold)
        
    # Flip b/w, and convert to uint8
    im_bw = np.array(~bw, dtype=np.uint8)*255
    
    algorithmNr = 0
    
    if algorithmNr == 0:
        labelled_array, num_features = spm.label(im_bw)
        sizes = spm.sum(bw, labelled_array, range(num_features))
        center = spm.center_of_mass(bw, labelled_array, np.argmax(sizes))    
        center = [center[1], center[0]]
    
    elif algorithmNr == 1:
        # Fill the corners
        # Note that the mask has to be 2 pixels larger than the image!
        mask = np.zeros( (h+2,w+2), dtype=np.uint8)
        cv2.floodFill(im_bw, mask, (1,h-1), 255)
        
        # After the floodfill operation, the "mask" indicates which areas have
        # been filled. It therefore has to be re-set for the next filling task.
        mask = np.zeros( (h+2,w+2), dtype=np.uint8)
        cv2.floodFill(im_bw, mask, (w-1,h-1), 255)
        
        # Fill the holes in the pupil
        wHoles = im_bw.copy()
        mask = np.zeros( (h+2,w+2), dtype=np.uint8)
        cv2.floodFill(wHoles, mask, (1,1), 0)
        im_bw[wHoles==255] = 0
        
        # Close the image, to remove the eye-brows    
        radius = 25
        strEl = np.zeros((2*radius+1, 2*radius+1), dtype=np.uint8)
        cv2.circle(strEl, (radius,radius), radius, 255, -1)
        
        closed = cv2.morphologyEx(im_bw, cv2.MORPH_CLOSE, strEl)
        
        # find the edge
        edgeThresholds = (1000, 1000)
        edge = cv2.Canny(closed, edgeThresholds[0], edgeThresholds[1], apertureSize=5)
        
        # find the center of the edge
        edge_y, edge_x = np.where(edge==255)
        center = np.array([np.mean(edge_x), np.mean(edge_y)])
        
    if np.any(np.isnan(center)):
        center = np.zeros(2)
        
    return (center, threshold)
示例#30
0
文件: metrics.py 项目: Conxz/nipype
    def _eucl_cog(self, nii1, nii2):
        origdata1 = np.logical_and(nii1.get_data() != 0, np.logical_not(np.isnan(nii1.get_data())))
        cog_t = np.array(center_of_mass(origdata1.copy())).reshape(-1, 1)
        cog_t = np.vstack((cog_t, np.array([1])))
        cog_t_coor = np.dot(nii1.affine, cog_t)[:3, :]

        origdata2 = np.logical_and(nii2.get_data() != 0, np.logical_not(np.isnan(nii2.get_data())))
        (labeled_data, n_labels) = label(origdata2)

        cogs = np.ones((4, n_labels))

        for i in range(n_labels):
            cogs[:3, i] = np.array(center_of_mass(origdata2,
                                                  labeled_data, i + 1))

        cogs_coor = np.dot(nii2.affine, cogs)[:3, :]

        dist_matrix = cdist(cog_t_coor.T, cogs_coor.T)

        return np.mean(dist_matrix)
示例#31
0
 def stack_all(self, mode='median', save=False):
     """
   Stack all PSF stars to produce a PSF image in the original pixel scale.
   """
     output = 'psf_stacked_raw_%s_%s_mag%.2f.fits' % (self.band, mode,
                                                      1. / self.factor)
     if os.path.exists(output):
         os.remove(output)
     iraf.imcombine(input='@psflist',
                    output=output,
                    combine=mode,
                    reject='sigclip',
                    lsigma=3.0,
                    hsigma=3.0,
                    mclip='yes',
                    nkeep=3)
     shape2 = np.array(pyfits.getdata(output).shape)
     # Now re-sample the image back to the original pixel scale
     output2 = 'psf_stacked_%s_%s.fits' % (self.band, mode)
     if os.path.exists(output2):
         os.remove(output2)
     # pm = image_moments.moments(pyfits.getdata(output))
     # pm.firstorder()
     pm1 = measurements.center_of_mass(pyfits.getdata(output))
     print "Oversampled PSF shape:", shape2
     print "Centroid before shift: %.2f, %.2f" % tuple(pm1)
     print "Shifted PSF image:", output2
     # AND REMEMBER TO SWAP X & Y if using IRAF!
     # iraf.imlintran(input=output,
     #                output=output2,
     #                xrotation=0., yrotation=0.,
     #                xin=pm.y1, yin=pm.x1,
     #                xmag=self.factor, ymag=self.factor,
     #                ncols=shape2[0]/self.factor, nlines=shape2[1]/self.factor,
     #                interpolant=self.interpolant)
     xshift = shape2[0] / 2. - pm1[0]
     yshift = shape2[1] / 2. - pm1[1]
     output_data = pyfits.getdata(output)
     print "xshift, yshift:", xshift, yshift
     output2_data = interpolation.shift(output_data, [xshift, yshift],
                                        order=1,
                                        mode='wrap')
     # check the new psf is centered...
     pm2 = measurements.center_of_mass(output2_data)
     print "Shifted center of mass: %.2f, %.2f" % tuple(pm2)
     # Now zoom the PSF back to the original pixel scale
     output2_data = interpolation.zoom(output2_data,
                                       1. / self.factor,
                                       order=1,
                                       mode='wrap')
     pyfits.append(output2, output2_data, pyfits.getheader(output))
     # Now center the PSF
     # pm2 = image_moments.moments(pyfits.getdata(output2))
     # npix = np.min(pyfits.getdata(output2).shape)
     # print "npix", npix
     # iraf.imlintran(input=output2, output='temp.fits',
     #                xrotation=0., yrotation=0.,
     #                xin=pm2.x1+1, yin=pm2.y1+1,
     #                xmag=1.0, ymag=1.0,
     #                ncols=npix, nlines=npix,
     #                interpolant='linear')
     # Now normalize the PSF
     # imgsum = pyfits.getdata(output2).ravel().sum()
     imgsum = output2_data.sum()
     imgsum = np.abs(imgsum)
     iraf.imarith(output2, '/', imgsum, 'temp.fits')
     os.remove(output2)
     os.system('mv temp.fits %s' % output2)
     os.system('rm temp*.fits')
     if not save:
         print "Removing %s..." % output
         os.remove(output)
    def addImg(self, img, roi=None):
        '''
        img - background, flat field, ste corrected image
        roi - [(x1,y1),...,(x4,y4)] -  boundaries where points are
        '''
        self.img = imread(img, 'gray')
        s0, s1 = self.img.shape

        if roi is None:
            roi = ((0, 0), (s0, 0), (s0, s1), (0, s1))

        k = self.kernel_size
        hk = k // 2

        # mask image
        img2 = self.img.copy()  # .astype(int)

        mask = np.zeros(self.img.shape)
        cv2.fillConvexPoly(mask, np.asarray(roi, dtype=np.int32), color=1)
        mask = mask.astype(bool)
        im = img2[mask]

        bg = im.mean()  # assume image average with in roi == background
        mask = ~mask
        img2[mask] = -1

        # find points from local maxima:
        self.points = np.zeros(shape=(self.max_points, 2), dtype=int)
        thresh = 0.8 * bg + 0.2 * im.max()

        _findPoints(img2, thresh, self.min_dist, self.points)
        self.points = self.points[:np.argmin(self.points, axis=0)[0]]

        # correct point position, to that every point is over max value:
        for n, p in enumerate(self.points):
            sub = self.img[p[1] - hk:p[1] + hk + 1, p[0] - hk:p[0] + hk + 1]
            i, j = np.unravel_index(np.nanargmax(sub), sub.shape)
            self.points[n] += [j - hk, i - hk]

        # remove points that are too close to their neighbour or the border
        mask = maximum_filter(mask, hk)
        i = np.ones(self.points.shape[0], dtype=bool)
        for n, p in enumerate(self.points):
            if mask[p[1], p[0]]:  # too close to border
                i[n] = False
            else:
                # too close to other points
                for pp in self.points[n + 1:]:
                    if norm(p - pp) < hk + 1:
                        i[n] = False
        isum = i.sum()
        ll = len(i) - isum
        print('found %s points' % isum)
        if ll:
            print('removed %s points (too close to border or other points)' %
                  ll)
            self.points = self.points[i]

#         self.n_points += len(self.points)

# for finding best peak position:
#         def fn(xy,cx,cy):#par
#             (x,y) = xy
#             return 1-(((x-cx)**2 + (y-cy)**2)*(1/8)).flatten()

#         x,y = np.mgrid[-2:3,-2:3]
#         x = x.flatten()
#         y = y.flatten()
# for shifting peak:
        xx, yy = np.mgrid[0:k, 0:k]
        xx = xx.astype(float)
        yy = yy.astype(float)

        self.subs = []

        #         import pylab as plt
        #         plt.figure(20)
        #         img = self.drawPoints()
        #         plt.imshow(img, interpolation='none')
        # #                 plt.figure(21)
        # #                 plt.imshow(sub2, interpolation='none')
        #         plt.show()

        #thresh = 0.8*bg + 0.1*im.max()
        for i, p in enumerate(self.points):
            sub = self.img[p[1] - hk:p[1] + hk + 1,
                           p[0] - hk:p[0] + hk + 1].astype(float)
            sub2 = sub.copy()

            mean = sub2.mean()
            mx = sub2.max()
            sub2[sub2 < 0.5 * (mean + mx)] = 0  # only select peak
            try:
                # SHIFT SUB ARRAY to align peak maximum exactly in middle:
                # only eval a 5x5 array in middle of sub:
                # peak = sub[hk-3:hk+4,hk-3:hk+4]#.copy()

                #                 peak -= peak.min()
                #                 peak/=peak.max()
                #                 peak = peak.flatten()
                # fit paraboloid to get shift in x,y:
                #                 p, _ = curve_fit(fn, (x,y), peak, (0,0))
                c0, c1 = center_of_mass(sub2)

                #                 print (p,c0,c1,hk)

                #coords = np.array([xx+p[0],yy+p[1]])
                coords = np.array([xx + (c0 - hk), yy + (c1 - hk)])

                #print (c0,c1)

                #import pylab as plt
                #plt.imshow(sub2, interpolation='none')

                # shift array:
                sub = map_coordinates(sub, coords,
                                      mode='nearest').reshape(k, k)
                # plt.figure(2)
                #plt.imshow(sub, interpolation='none')
                # plt.show()

                #normalize:
                bg = 0.25 * (sub[0].mean() + sub[-1].mean() +
                             sub[:, 0].mean() + sub[:, -1].mean())

                sub -= bg
                sub /= sub.max()

                #                 import pylab as plt
                #                 plt.figure(20)
                #                 plt.imshow(sub, interpolation='none')
                # #                 plt.figure(21)
                # #                 plt.imshow(sub2, interpolation='none')
                #                 plt.show()

                self._psf += sub

                if self.calc_std:
                    self.subs.append(sub)
            except ValueError:
                pass  #sub.shape == (0,0)
示例#33
0
def nema_2008_small_animal_pet_rois(vol, voxsize, lp_voxel = 'max', rod_th = 0.15,
                                    phantom = 'standard'):
  """ generate a label volume indicating the ROIs needed in the analysis of the
      NEMA small animal PET IQ phantom

  Parameters
  ----------
  vol : 3D numpy float array
    containing the image

  voxsize : 3 element 1D numpy array
    containing the voxel size

  lp_voxel: string, optional
    method of how to compute the pixel used to draw the line profiles
    in the rods. 'max' means the maximum voxels in the summed 2D image.
    anything else means use the center of mass.
 
  rod_th : float, optional
    threshold to find the rod in the summed 2D image relative to the
    mean of the big uniform region

  phantom : string
    phantom version ('standard' or 'mini')
 
  Returns
  -------
  a 3D integer numpy array
    encoding the following ROIs:
    1 ... ROI of the big uniform region
    2 ... first cold insert
    3 ... second cold insert
    4 ... central line profile in 5mm rod
    5 ... central line profile in 4mm rod
    6 ... central line profile in 3mm rod
    7 ... central line profile in 2mm rod
    8 ... central line profile in 1mm rod

  Note
  ----
  The rod ROIs in the summed 2D image are found by thresholding.
  If the activity in the small rods is too low, they might be missed.
  """
  roi_vol = np.zeros(vol.shape, dtype = np.uint)
  
  # calculate the summed z profile to place the ROIs
  zprof      = vol.sum(0).sum(0)
  zprof_grad = np.gradient(zprof)
  zprof_grad[np.abs(zprof_grad) < 0.13*np.abs(zprof_grad).max()] = 0
  
  rising_edges  = argrelextrema(zprof_grad, np.greater, order = 10)[0]
  falling_edges = argrelextrema(zprof_grad, np.less, order = 10)[0]
 
  # if we only have 2 falling edges because the volume is cropped, we add the last slices as 
  # falling edge

  if falling_edges.shape[0] == 2:
    falling_edges = np.concatenate([falling_edges,[vol.shape[2]]])

  # define and analyze the big uniform ROI
  uni_region_start_slice  = rising_edges[1]
  uni_region_end_slice    = falling_edges[1]
  uni_region_center_slice = 0.5*(uni_region_start_slice + uni_region_end_slice) 
  
  uni_roi_start_slice = int(np.floor(uni_region_center_slice - 5./voxsize[2]))
  uni_roi_end_slice   = int(np.ceil(uni_region_center_slice  + 5./voxsize[2]))
  
  uni_com = np.array(center_of_mass(vol[:,:,uni_roi_start_slice:(uni_roi_end_slice+1)]))
  
  x0 = (np.arange(vol.shape[0]) - uni_com[0]) * voxsize[0]
  x1 = (np.arange(vol.shape[1]) - uni_com[1]) * voxsize[1]
  x2 = (np.arange(vol.shape[2]) - uni_com[2]) * voxsize[2]
  
  X0,X1,X2 = np.meshgrid(x0,x1,x2,indexing='ij')
  RHO      = np.sqrt(X0**2 + X1**2)
  
  uni_mask = np.zeros(vol.shape, dtype = np.uint)
  if phantom == 'standard':
    uni_mask[RHO <= 11.25] = 1
  elif phantom == 'mini':
    uni_mask[RHO <= 6.25] = 1
  uni_mask[:,:,:uni_roi_start_slice]   = 0
  uni_mask[:,:,(uni_roi_end_slice+1):] = 0
  
  uni_inds = np.where(uni_mask == 1)
  roi_vol[uni_inds] = 1
  
  # define and analyze the two cold ROIs
  insert_region_start_slice  = falling_edges[1]
  insert_region_end_slice    = falling_edges[2]
  insert_region_center_slice = 0.5*(insert_region_start_slice + insert_region_end_slice) 
  
  insert_roi_start_slice = int(np.floor(insert_region_center_slice - 3.75/voxsize[2]))
  insert_roi_end_slice   = int(np.ceil(insert_region_center_slice  + 3.75/voxsize[2]))
  
  # sum the insert slices and subtract them from the max to find the two cold inserts
  sum_insert_img = vol[:,:,insert_roi_start_slice:(insert_roi_end_slice+1)].mean(2)
 
  ref = np.percentile(sum_insert_img,99)
  if phantom == 'standard':
    insert_label_img, nlab_insert = label(sum_insert_img <= 0.5*ref)
  elif phantom == 'mini':
    # reset pixels outside the phantom, since inserts sometimes leak into background
    tmp_inds = RHO[:,:,0] > 9
    sum_insert_img[tmp_inds] = ref
    insert_label_img, nlab_insert = label(binary_erosion(sum_insert_img <= 0.5*ref))

    # add backgroud low activity ROI to be compliant with standard phantom
    insert_label_img[tmp_inds] = 3
    nlab_insert += 1

  insert_labels = np.arange(1,nlab_insert+1)
  # sort the labels according to volume
  npix_insert   = labeled_comprehension(sum_insert_img, insert_label_img, insert_labels, len, int, 0)
  insert_sort_inds = npix_insert.argsort()[::-1]
  insert_labels    = insert_labels[insert_sort_inds] 
  npix_insert      = npix_insert[insert_sort_inds] 

  for i_insert in [1,2]:
    tmp = insert_label_img.copy()
    tmp[insert_label_img != insert_labels[i_insert]] = 0
    com_pixel = np.round(np.array(center_of_mass(tmp)))
  
    x0 = (np.arange(vol.shape[0]) - com_pixel[0]) * voxsize[0]
    x1 = (np.arange(vol.shape[1]) - com_pixel[1]) * voxsize[1]
    x2 = (np.arange(vol.shape[2])) * voxsize[2]
    
    X0,X1,X2 = np.meshgrid(x0,x1,x2,indexing='ij')
    RHO      = np.sqrt(X0**2 + X1**2)
  
    insert_mask = np.zeros(vol.shape, dtype = np.uint)
    insert_mask[RHO <= 2] = 1
    insert_mask[:,:,:insert_roi_start_slice]   = 0
    insert_mask[:,:,(insert_roi_end_slice+1):] = 0
  
    insert_inds = np.where(insert_mask == 1)
    roi_vol[insert_inds] = i_insert + 1
  
  # find the rod z slices
  rod_start_slice = falling_edges[0]
  rod_end_slice   = rising_edges[1]
  rod_center      = 0.5*(rod_start_slice + rod_end_slice)
  
  rod_roi_start_slice = int(np.floor(rod_center - 5./voxsize[2]))
  rod_roi_end_slice   = int(np.ceil(rod_center  + 5./voxsize[2]))
  
  # sum the rod slices
  sum_img = vol[:,:,rod_roi_start_slice:(rod_roi_end_slice+1)].mean(2)
  
  # label the summed image
  label_img, nlab = label(sum_img > rod_th*sum_img.max())
  labels = np.arange(1,nlab+1)

  # sort the labels according to volume
  npix      = labeled_comprehension(sum_img, label_img, labels, len, int, 0)
  sort_inds = npix.argsort()[::-1]
  labels    = labels[sort_inds] 
  npix      = npix[sort_inds] 
  
  # find the center for the line profiles
  for i, lab in enumerate(labels):
    rod_sum_img = sum_img.copy()
    rod_sum_img[label_img != lab] = 0
 
    if lp_voxel == 'max':
      central_pixel = np.unravel_index(rod_sum_img.argmax(),rod_sum_img.shape)
    else:
      central_pixel = np.round(np.array(center_of_mass(rod_sum_img))).astype(np.int)
  
    roi_vol[central_pixel[0],central_pixel[1],rod_roi_start_slice:(rod_roi_end_slice+1)] = i + 4

  #-------------------------------------------------------
  # if we only have 4 labels (rods), we find the last (smallest) one based on symmetries
  if nlab == 4:
    roi_img = roi_vol[...,rod_roi_start_slice]

    com = center_of_mass(roi_vol == 1)
    x0 = (np.arange(sum_img.shape[0]) - com[0]) * voxsize[0]
    x1 = (np.arange(sum_img.shape[1]) - com[1]) * voxsize[1]
    X0,X1 = np.meshgrid(x0, x1, indexing = 'ij')
    RHO = np.sqrt(X0**2 + X1**2)

    PHI = np.arctan2(X1,X0)
    rod_phis = np.array([PHI[roi_img == x][0] for x in np.arange(4,nlab+4)])
    PHI      = ((PHI - rod_phis[3]) % (2*np.pi)) - np.pi
    rod_phis = ((rod_phis - rod_phis[3]) % (2*np.pi)) - np.pi
    
    missing_phi = ((rod_phis[3] - rod_phis[2]) % (2*np.pi)) - np.pi
    
    mask = np.logical_and(np.abs(PHI - missing_phi) < 0.25, np.abs(RHO - 6.4) < 2)
    
    central_pixel = np.unravel_index(np.argmax(sum_img*mask), sum_img.shape)
    roi_vol[central_pixel[0],central_pixel[1],rod_roi_start_slice:(rod_roi_end_slice+1)] = 8

    nlab += 1
  #-------------------------------------------------------


  return roi_vol
示例#34
0
def heatmap(im, model, patch_shape, mean_train, std_train, brain_bool=True):
    """Compute the heatmap with CNN_1 representing the SC localization."""
    data_im = im.data.astype(np.float32)
    im_out = change_type(im, "uint8")
    del im
    data = np.zeros(im_out.data.shape)

    x_shape, y_shape = data_im.shape[:2]
    x_shape_block, y_shape_block = np.ceil(x_shape * 1.0 / patch_shape[0]).astype(np.int), np.int(
        y_shape * 1.0 / patch_shape[1])
    x_pad = int(x_shape_block * patch_shape[0] - x_shape)
    if y_shape > patch_shape[1]:
        y_crop = y_shape - y_shape_block * patch_shape[1]
        # slightly crop the input data in the P-A direction so that data_im.shape[1] % patch_shape[1] == 0
        data_im = data_im[:, :y_shape - y_crop, :]
        # coordinates of the blocks to scan during the detection, in the cross-sectional plane
        coord_lst = [[x_dim * patch_shape[0], y_dim * patch_shape[1],
                      (x_dim + 1) * patch_shape[0], (y_dim + 1) * patch_shape[1]]
                     for y_dim in range(y_shape_block) for x_dim in range(x_shape_block)]
    else:
        data_im = np.pad(data_im, ((0, 0), (0, patch_shape[1] - y_shape), (0, 0)), 'constant')
        coord_lst = [[x_dim * patch_shape[0], 0, (x_dim + 1) * patch_shape[0], patch_shape[1]] for x_dim in
                     range(x_shape_block)]
    # pad the input data in the R-L direction
    data_im = np.pad(data_im, ((0, x_pad), (0, 0), (0, 0)), 'constant')
    # scale intensities between 0 and 255
    data_im = scale_intensity(data_im)

    x_CoM, y_CoM = None, None
    z_sc_notDetected_cmpt = 0
    for zz in range(data_im.shape[2]):
        # if SC was detected at zz-1, we will start doing the detection on the block centered around the previously
        # computed center of mass (CoM)
        if x_CoM is not None:
            z_sc_notDetected_cmpt = 0  # SC detected, cmpt set to zero
            x_0, x_1 = _find_crop_start_end(x_CoM, patch_shape[0], data_im.shape[0])
            y_0, y_1 = _find_crop_start_end(y_CoM, patch_shape[1], data_im.shape[1])
            block = data_im[x_0:x_1, y_0:y_1, zz]
            block_nn = np.expand_dims(np.expand_dims(block, 0), -1)
            block_nn_norm = _normalize_data(block_nn, mean_train, std_train)
            block_pred = model.predict(block_nn_norm, batch_size=BATCH_SIZE)

            # coordinates manipulation due to the above padding and cropping
            if x_1 > data.shape[0]:
                x_end = data.shape[0]
                x_1 = data.shape[0]
                x_0 = data.shape[0] - patch_shape[0] if data.shape[0] > patch_shape[0] else 0
            else:
                x_end = patch_shape[0]
            if y_1 > data.shape[1]:
                y_end = data.shape[1]
                y_1 = data.shape[1]
                y_0 = data.shape[1] - patch_shape[1] if data.shape[1] > patch_shape[1] else 0
            else:
                y_end = patch_shape[1]

            data[x_0:x_1, y_0:y_1, zz] = block_pred[0, :x_end, :y_end, 0]

            # computation of the new center of mass
            if np.max(data[:, :, zz]) > 0.5:
                z_slice_out_bin = data[:, :, zz] > 0.5  # if the SC was detection
                x_CoM, y_CoM = center_of_mass(z_slice_out_bin)
                x_CoM, y_CoM = int(x_CoM), int(y_CoM)
            else:
                x_CoM, y_CoM = None, None

        # if the SC was not detected at zz-1 or on the patch centered around CoM in slice zz, the entire cross-sectional
        # slice is scanned
        if x_CoM is None:
            z_slice, x_CoM, y_CoM, coord_lst = scan_slice(data_im[:, :, zz], model,
                                                          mean_train, std_train,
                                                          coord_lst, patch_shape, data.shape[:2])
            data[:, :, zz] = z_slice

            z_sc_notDetected_cmpt += 1
            # if the SC has not been detected on 10 consecutive z_slices, we stop the SC investigation
            if z_sc_notDetected_cmpt > 10 and brain_bool:
                sct.printv('Brain section detected.')
                break

        # distance transform to deal with the harsh edges of the prediction boundaries (Dice)
        data[:, :, zz][np.where(data[:, :, zz] < 0.5)] = 0
        data[:, :, zz] = distance_transform_edt(data[:, :, zz])

    if not np.any(data):
        logger.error(
            '\nSpinal cord was not detected using "-centerline cnn". Please try another "-centerline" method.\n')
        sys.exit(1)

    im_out.data = data

    # z_max is used to reject brain sections
    z_max = np.max(list(set(np.where(data)[2])))
    if z_max == data.shape[2] - 1:
        return im_out, None
    else:
        return im_out, z_max
示例#35
0
def attenuation_iaf(raws, picks=None,  # noqa: C901
                    fmin=None, fmax=None,
                    resolution=0.25,
                    average=True,
                    ax=None,
                    savgol=False,
                    window_length=11, polyorder=5,
                    flat_max_r=0.98):
    """Estimate individual alpha frequency (IAF).

    Parameters
    ----------
    raws : list-like of Raw
        Two Raws to calculate IAF from difference (attenuation) in PSD from.
    picks : array-like of int | None
        List of channels to use.
    fmin : int | None
        Lower bound of alpha frequency band. If None, it will be
        empirically estimated using a polynomial fitting method to
        determine the edges of the central parabolic peak density,
        with assumed center of 10 Hz.
    fmax : int | None
        Upper bound of alpha frequency band. If None, it will be
        empirically estimated using a polynomial fitting method to
        determine the edges of the central parabolic peak density,
        with assumed center of 10 Hz.
    resolution : float
        The resolution in the frequency domain for calculating the PSD.
    average : bool
        Whether to average the PSD estimates across channels or provide
        a separate estimate for each channel. Currently, only True is
        supported.
    ax : instance of matplotlib Axes | None | False
        Axes to plot PSD analysis into. If None, axes will be created
        (and plot not shown by default). If False, no plotting will be done.
    savgol : False | 'each' | 'diff'
        Use Savitzky-Golay filtering to smooth PSD estimates -- either applied
        to either each PSD estimate or to the difference (i.e. the attenuation
        estimate).
    window_length : int
        Window length in samples to use for Savitzky-Golay smoothing of
        PSD when estimating IAF.
    polyorder : int
        Polynomial order to use for Savitzky-Golay smoothing of
        PSD when estimating IAF.
    flat_max_r: float
        Maximum (Pearson) correlation allowed when comparing the raw PSD
        distributions to each other in the range 1 to 30 Hz.
        If this threshold is exceeded, then IAF is assumed unclear and
        None is returned for both PAF and CoG. Note that the sign of the
        coefficient is ignored.

    Returns
    -------
    IafEst : instance of ``collections.namedtuple`` called IAFEstimate

         Named tuple with fields for the peak alpha frequency (PAF),
         alpha center of gravity (CoG), and the bounds of the alpha band
         (as a tuple).

    Notes
    -----
    Based on method developed by
    `Andrew Corcoran <https://zenodo.org/badge/latestdoi/80904585>`_.
    In addition to appropriate software citation (Zenodo DOI or
    git commit), please cite:

        Corcoran, A. W., Alday, P. M., Schlesewsky, M., &
        Bornkessel-Schlesewsky, I. (2018). Toward a reliable, automated method
        of individual alpha frequency (IAF) quantification. Psychophysiology,
        e13064. doi:10.1111/psyp.13064

    """
    # TODO: check value of savgol parameter
    def psd_est(r):
        n_fft = int(r.info['sfreq'] / resolution)
        return mne.time_frequency.psd_welch(r, picks=picks, n_fft=n_fft,
                                            fmin=1., fmax=30.)

    psd, freqs = zip(*[psd_est(r) for r in raws])
    assert np.allclose(*freqs)

    if savgol == 'each':
        psd = [savgol_filter(p,
                             window_length=window_length,
                             polyorder=polyorder) for p in psd]

    att_psd = psd[1] - psd[0]

    if average:
        att_psd = np.mean(att_psd, axis=0)
        psd = [np.mean(p, axis=0) for p in psd]

    att_psd = np.abs(att_psd)

    att_freqs = freqs[0]

    if ax is None:
        fig = plt.figure()  # noqa: F841
        ax = plt.gca()

    if fmin is None or fmax is None:
        if fmin is None:
            fmin_bound = 5
        else:
            fmin_bound = fmin

        if fmax is None:
            fmax_bound = 15
        else:
            fmax_bound = fmax

        alpha_search = np.logical_and(att_freqs >= fmin_bound,
                                      att_freqs <= fmax_bound)
        freqs_search = att_freqs[alpha_search]
        # set the window to the entire interval
        # don't use the sname window_length because that's used as a
        # parameter for the function as a whole
        wlen = att_psd[alpha_search].shape[0]
        psd_search = savgol_filter(att_psd[alpha_search],
                                   window_length=wlen,
                                   polyorder=10)
        # argrel min returns a tuple, so we flatten that with [0]
        # then we get the last element of the resulting array with [-1]
        # which is the minimum closest to the 'median' alpha of 10 Hz
        if fmin is None:
            try:
                left_min = argrelmin(psd_search[freqs_search < 10])[0][-1]
                fmin = freqs_search[freqs_search < 10][left_min]
            except IndexError:
                raise ValueError("Unable to automatically determine lower end of alpha band.") # noqa: 501
        if fmax is None:
            # here we want the first element of the array which is closest to
            # the 'median' alpha of 10 Hz
            try:
                right_min = argrelmin(psd_search[freqs_search > 10])[0][0]
                fmax = freqs_search[freqs_search > 10][right_min]
            except IndexError:
                raise ValueError("Unable to automatically determine upper end of alpha band.")  # noqa: 501

    if savgol == 'diff':
        att_psd = savgol_filter(att_psd,
                                window_length=window_length,
                                polyorder=polyorder)

    alpha_band = np.logical_and(att_freqs >= fmin, att_freqs <= fmax)

    r, p = stats.pearsonr(psd[0], psd[1])

    if np.abs(r) > np.abs(flat_max_r):
        paf = None
        cog = None
    else:
        paf_idx = np.argmax(att_psd[alpha_band])
        paf = att_freqs[alpha_band][paf_idx]

        cog_idx = center_of_mass(att_psd[alpha_band])
        cog_idx = int(np.round(cog_idx[0]))
        cog = att_freqs[alpha_band][cog_idx]

    if ax:
        sgnote = '(with SG-Smoothing)' if savgol == 'each' else ''
        plt_psd1, = ax.plot(freqs[0], psd[0],
                            label="Raw PSD #1 {}".format(sgnote))
        plt_psd2, = ax.plot(freqs[1], psd[1],
                            label="Raw PSD #2 {}".format(sgnote))

        sgnote = '(with SG-Smoothing)' if savgol == 'diff' else ''
        plt_att_psd, = ax.plot(att_freqs, att_psd,
                               label="Attenuated PSD {}".format(sgnote))
#         plt_pink, = ax.plot(att_freqs,
#                      np.exp(slope * np.log(att_freqs) + intercept),
#                      label='$1/f$ fit ($R^2={:0.2}$)'.format(r**2))
        ax.text(np.max(att_freqs) * 0.5, np.max(att_psd) * 0.67,
                'Raw PSD Pearson $r={:0.2}$'.format(r))
        try:
            plt_search, = ax.plot(freqs_search, psd_search,
                                  label='Alpha-band Search Parabola')
            ax.legend(handles=[plt_psd1, plt_psd2, plt_att_psd, plt_search])
        except UnboundLocalError:
            # this happens when the user fully specified an alpha band
            ax.legend(handles=[plt_psd1, plt_psd2, plt_att_psd])

        ax.set_ylabel("PSD")
        ax.set_xlabel("Hz")

    return IafEst(paf, cog, (fmin, fmax))
示例#36
0
n_centroids_to_keep = 30
labeled, nr_objects = mh.label(bw)
sizes = mh.labeled.labeled_size(
    labeled
)  # size[0] is the background size, sizes[1 and greater] are number of pixels in each region
sorted_sizes_indexes = np.argsort(sizes)[::-1]  # return in descending order
good_spot_indexes = sorted_sizes_indexes[
    1:n_centroids_to_keep +
    1]  # avoiding the background regions entry at the beginning

FWHMSub = []
xCenSub = []
yCenSub = []
peaks = []
fluxes = []
centers = center_of_mass(labeled, labels=labeled, index=[good_spot_indexes])

nbox = 20
for i, x in enumerate(centers):
    x = x[0]
    px = int(round(x[1]))
    py = int(round(x[0]))
    data = img[py - nbox:py + nbox, px - nbox:px + nbox]
    params = fitgaussian(data)
    fwhm = abs(2.355 * max(params[4], params[5]))
    if fwhm < .5:
        print(" fit failed - trying again with smaller fitbox")
        sbox = nbox - 1
        data = img[py - sbox:py + sbox, px - sbox:px + sbox]
        params = fitgaussian(data)
        fwhm = abs(2.355 * max(params[4], params[5]))
示例#37
0
index_offset = 0
for index in range(nb_img):
    if detector == 1:
        rawdata[index, :, :], mask = remove_hotpixels_maxipix(
            rawdata[index, :, :], mask, hotpixels_file)
        rawdata[index, :, :], mask = mask_maxipix(rawdata[index, :, :], mask)
        flatfield[mask == 1] = 0
        rawdata[index, :, :] = rawdata[index, :, :] * flatfield
        piy, pix = np.unravel_index(rawdata[index, :, :].argmax(),
                                    rawdata[index, :, :].shape)

    sum_data = sum_data + rawdata[index, :, :]
    if index not in frames_to_exclude:
        if use_rawdata == 0:
            y0, x0 = center_of_mass(rawdata[index, :, :])
            data[index - index_offset, piy - window_ver:piy + window_ver + 1,
                 pix - window_hor:pix + window_hor +
                 1, ] = rawdata[index, piy - window_ver:piy + window_ver + 1,
                                pix - window_hor:pix + window_hor + 1, ]
        else:
            data[index - index_offset, :, :] = rawdata[index, :, :]
        delta[index - index_offset] = raw_delta[index]
        gamma[index - index_offset] = raw_gamma[index]
    else:
        index_offset = index_offset + 1
        print("Frame index", str(index), "excluded")
plt.ion()
plt.figure()
plt.imshow(np.log10(sum_data))
plt.title("Sum of all frames")
示例#38
0
def contourcuts(image,
                maxdist=15,
                minrange=10,
                mincdist=20,
                sigma=1.0,
                debug=0,
                r=8,
                s=0.5):
    if debug:
        figure(1)
        clf()
        imshow(image)

    # start by computing the contours
    contours = image2contours(image != 0)

    # generate a mask for grayscale morphology
    mask = s * ones((r, r))
    mask[2:-2, 2:-2] = 0

    cuts = []

    # now handle each (external) contour individually
    for k, cs in enumerate(contours):
        # compute a matrix of all the pairwise distances of pixels
        # around the contour, then smooth it a little
        ds = distance.cdist(cs, cs)
        ds = filters.gaussian_filter(ds, (sigma, sigma), mode='wrap')
        # compute a circulant matrix telling us the pathlength
        # between any two pixels on the contour
        n = len(cs)
        l = abs(arange(n) - n / 2.0)
        l = l[0] - l
        cds = linalg.circulant(l)

        # find true local minima (exclude ridges) by using the
        # structuring element above
        ge = morphology.grey_erosion(ds, structure=mask, mode='wrap')
        locs = (ds <= ge)

        # restrict it to pairs of points that are closer than maxdist
        locs *= (ds < maxdist)

        # restrict it to paris of points that are separated by
        # at least mincdist on the contour
        locs *= (cds >= mincdist)

        # label the remaining minima and locate them
        locs, n = measurements.label(locs)
        cms = measurements.center_of_mass(locs, locs, range(1, n + 1))

        # keep only on of each pair (in canonical ordering)
        cms = [(int(i + 0.5), int(j + 0.5)) for i, j in cms if i < j]
        for i, j in cms:
            x0, y0 = cs[i]
            x1, y1 = cs[j]
            # keep only the near vertical ones
            if abs(y1 - y0) > abs(x1 - x0):
                color = 'r'
                cuts.append((cs[i], cs[j]))
            else:
                color = 'b'
            if debug:
                print(x0, y0), (x1, y1)
                figure(1)
                plot([x0, x1], [y0, y1], color)

        if debug:
            figure(2)
            clf()
            ion()
            imshow(locs != 0)
            figure(3)
            clf()
            imshow(minimum(ds, maxdist * 1.5), interpolation='nearest')
            ginput(1, 0.1)
            print "hit ENTER"
            raw_input()
    # now construct a cut image
    cutimage = zeros(image.shape)
    for ((x0, y0), (x1, y1)) in cuts:
        image_draw_line(cutimage, y0, x0, y1, x1)
    cutimage = filters.maximum_filter(cutimage, (3, 3))
    if debug:
        figure(4)
        clf()
        imshow(maximum(0, image - 0.5 * cutimage))
    return cutimage
示例#39
0
cv2.destroyAllWindows()
#%%
threshold=95
imCrop[imCrop<threshold] = 0
f1lab,f1num = measurements.label(imCrop)
f1slices = measurements.find_objects(f1lab)
min_size=9
cal_points = []
for s, f1slice in enumerate(f1slices):
    imCopy = np.zeros(imCrop.shape)
    img_object = imCrop[f1slice]*(f1lab[f1slice]==(s+1))
    obj_size = np.count_nonzero(img_object)
    #threshold objects based on size
    if obj_size > min_size: 
        imCopy[f1slice] = img_object
        centroid = measurements.center_of_mass(imCopy)
        cal_points.append(np.array([s,f1slice,centroid[1]+0.5,centroid[0]+0.5]))
cal_points=np.asarray(cal_points)

#%%
pts = 6
c = np.array([r[0],r[1]])
plt.figure(1)
plt.pcolormesh((imCrop),cmap=cm.gray)
plt.plot(cal_points[:,2],cal_points[:,3],'rx')
print('Choose shared points between images')
x=[]
for i in range(0,pts):
    x0 = plt.ginput(1)[0]
    dist = (cal_points[:,3]-x0[1])**2+(cal_points[:,2]-x0[0])**2
    (mindist, i0) = (dist.min(),np.where(dist==dist.min())[0])
示例#40
0
def _get_intensities_summation_method(
    z,
    vectors,
    box_inner: int = 7,
    box_outer: int = 10,
    n_min: int = 5,
    n_max: int = None,
    snr_thresh=3.0,
    verbose: bool = False,
):
    """Integrate reflections using the summation method. Two boxes are defined,
    the inner box is used to define the integration area. The outer box is used
    to calculate the average signal-to-noise ratio (SNR).

    All pixels with a large enough SNR are considered to be signal. The largest region
    of connected signal pixels are summed to calculate the reflection intensity.

    Parameters
    ----------
    vectors : DiffractionVectors
        Vectors to the locations of the spots to be
        integrated.
    box_inner : int
        Defines the radius (size) of the inner box, which must be larger than the reflection.
        The total box size is 2*box_inner
    box_outer : int
        Defines radius (size) of the outer box. The total box size is 2*box_inner
        The border between the inner and outer box is considered background
        and used to calculate the (SNR) for each pixel: SNR = (I - <I>/std(I_bkg)).
    snr_thresh : float
        Minimum signal-to-noise for a pixel to be considered as `signal`.
    n_min: int
        If the number of SNR pixels in the inner box < n_min, the reflection is discared
    n_max:
        If the number of SNR pixels in the inner box >= n_max, the reflection is discareded
        Defaults to the inner box size (`box_inner**2`.
    verbose : bool
        Print statistics for every reflection (for debugging)

    Returns
    -------
    peaks : np.array
        Array with 4 columns: X-position, Y-position, intensity, reflection SNR

    Notes
    -----
    Implementation based on Barty et al, J. Appl. Cryst. (2014). 47, 1118-1131
                            Lesli, Acta Cryst. (2006). D62, 48-57
    """
    if not n_max:  # pragma: no cover
        n_max = box_inner ** 2

    peaks = []

    for i, j in vectors:
        box = z[j - box_inner : j + box_inner, i - box_inner : i + box_inner].copy()

        bkg = np.hstack(
            [
                z[j - box_outer : j + box_outer, i - box_outer : i - box_inner].ravel(),
                z[j - box_outer : j + box_outer, i + box_inner : i + box_outer].ravel(),
                z[j - box_outer : j - box_inner, i - box_inner : i + box_inner].ravel(),
                z[j + box_inner : j + box_outer, i - box_inner : i + box_inner].ravel(),
            ]
        )

        bkg_mean = bkg.mean()
        bkg_std = bkg.std()
        box_snr = (box - bkg_mean) / bkg_std

        # get mask for signal (I > SNR)
        signal_mask = _get_largest_connected_region(box_snr > snr_thresh)

        n_pix = signal_mask.sum()
        signal = (box - bkg_mean) * signal_mask
        inty = signal.sum()
        snr = (inty / n_pix) / bkg_std
        sigma = inty / snr

        # calculate center of mass
        com_X, com_Y = center_of_mass(box, labels=signal_mask, index=1)
        dX = com_X - box_inner
        dY = com_Y - box_inner

        X = i + dX
        Y = j + dY

        if verbose:  # pragma: no cover
            print(
                f"\nMean(I): {bkg_mean:.2f} | Std(I): {bkg_std:.2f} | n_pix: {n_pix} \n"
                f"I: {inty:.2f} | Sigma(I): {sigma:.2f} | SNR(I): {snr:.2f} | I/pix: {inty/n_pix:.2f} \n"
                f"i: {i:.2f} | j: {j:.2f} | dX: {dX:.2f} | dY: {dY:.2f} | X: {X:.2f} | Y: {Y:.2f} "
            )
            # for debugging purposes
            import matploltib.pyplot as plt

            plt.imshow(signal)
            plt.plot(dY + box_inner, dX + box_inner, "r+")  # center_of_mass
            plt.plot(box_inner, box_inner, "g+")  # input
            plt.show()

        if n_pix > n_max:  # pragma: no cover
            continue
        if n_pix < n_min:  # pragma: no cover
            continue

        # for some reason X/Y are reversed here
        peaks.append([Y, X, inty, sigma])

    peaks = np.array(peaks)

    return np.array(peaks)
示例#41
0
      detector.pixelsize_y, detector.pixelsize_x, '(m)')
diff_pattern = pu.bin_data(array=diff_pattern,
                           binning=phasing_binning,
                           debugging=False)
mask = pu.bin_data(array=mask, binning=phasing_binning, debugging=False)

numz, numy, numx = diff_pattern.shape  # this shape will be used for the calculation of q values
print(
    f'\nMeasured data shape = {numz}, {numy}, {numx}, Max(measured amplitude)={np.sqrt(diff_pattern).max():.1f}'
)
diff_pattern[np.nonzero(mask)] = 0

######################################################
# find the center of mass of the diffraction pattern #
######################################################
z0, y0, x0 = center_of_mass(diff_pattern)
print(f'COM of measured pattern after masking: {z0:.2f}, {y0:.2f}, {x0:.2f}')
# refine the COM in a small ROI centered on the approximate COM, to avoid detector gaps
fine_com = center_of_mass(diff_pattern[int(z0) - 20:int(z0) + 21,
                                       int(y0) - 20:int(y0) + 21,
                                       int(x0) - 20:int(x0) + 21])
z0, y0, x0 = [
    int(np.rint(z0 - 20 + fine_com[0])),
    int(np.rint(y0 - 20 + fine_com[1])),
    int(np.rint(x0 - 20 + fine_com[2]))
]
print(
    f'refined COM: {z0}, {y0}, {x0}, Number of unmasked photons = {diff_pattern.sum():.0f}\n'
)

fig, _, _ = gu.multislices_plot(np.sqrt(diff_pattern),
示例#42
0
def mask_to_transform(seg,
                      rotation=0.0,
                      margin=0.0,
                      radians=True,
                      return_images=False):

    assert seg.ndim == 2

    seg_original = seg.copy()
    seg = dv.binarize_array(seg)

    ##
    ## Calculate Useful Quantities
    ##

    ctr = [s // 2 for s in seg.shape]
    com = center_of_mass(seg)
    nrm = [
        2.0 * (i_com - i_ctr) / i_shp
        for i_com, i_ctr, i_shp in zip(com, ctr, seg.shape)
    ]
    ost = [-n * c for n, c in zip(nrm, ctr)]

    if radians:
        rotation = np.degrees(rotation)

    ##
    ## Translation
    ##

    seg_xy = itp.shift(seg, ost, order=0, mode="constant", cval=0)

    ##
    ## Rotation
    ##

    seg_rt = itp.rotate(seg_xy,
                        rotation,
                        reshape=False,
                        order=0,
                        mode="nearest")

    ##
    ## Zoom
    ##

    bbox = dv.bounding_box(seg_rt)

    scale = [(i_max - i_min) / i_shp
             for (i_min, i_max), i_shp in zip(bbox, seg.shape)]

    scale = max(scale)

    scale = min(1.0, scale + margin * 2.0)

    if return_images:
        seg_xy = itp.shift(seg_original, ost, order=0, mode="constant", cval=0)
        seg_rt = itp.rotate(seg_xy,
                            rotation,
                            reshape=False,
                            order=0,
                            mode="nearest")
        seg_zm = dv.crop_or_pad(itp.zoom(seg_rt, 1.0 / scale, order=0),
                                seg.shape)
        return nrm, -np.radians(rotation), scale, seg_xy, seg_rt, seg_zm
    else:
        return nrm, -np.radians(rotation), scale
示例#43
0
obj0, _ = util.load_file(file_path[0])
ndim = obj0.ndim
if ndim != 3:
    print('3D objects are expected')
    sys.exit()

nz, ny, nx = obj0.shape
obj0 = pu.crop_pad(array=obj0, output_shape=(nz+10, ny+10, nx+10))
nz, ny, nx = obj0.shape
print('Array shape', obj0.shape)

amp0 = abs(obj0)
sum0 = amp0.sum()
phase0 = np.angle(obj0)
if alignment_method in ['modulus', 'skip']:
    piz0, piy0, pix0 = center_of_mass(amp0)
else:  # 'support'
    support = np.zeros(amp0.shape)
    support[amp0 > support_threshold * amp0.max()] = 1
    piz0, piy0, pix0 = center_of_mass(support)

piz0, piy0, pix0 = int(piz0), int(piy0), int(pix0)
phase0 = phase0 - phase0[piz0, piy0, pix0]  # set the phase to 0 at the COM of the support
obj0 = amp0 * np.exp(1j * phase0)
stack = np.zeros((nbfiles, nz, ny, nx), dtype=complex)
stack[0, :, :, :] = obj0
del amp0, phase0
gc.collect()

for idx in range(1, nbfiles):
    print('\n' + os.path.basename(file_path[idx]))
示例#44
0
def findBlobs(S,Thresh=None,EdgeBound=None):
    '''
    Finds distinct blobs of a scalar that are bigger than a certain size (Thresh)
    Now new and improved! and much faster!
    
    Inputs:
    S - sets of 2D scalar fields that have already been thresholded (0s or 1s). The third dimension denotes the frame
    Thresh - Number of vectors that must be contained in a blob. If not defined, then no threshold filter will be used
    EdgeBound - Crops all blobs that are too close to the edge of the domain. No crop if left as none. 
    
    Outputs:
    cent - 
    labelled_array - The labeled array of blobs (in format of ndimage.measurements.label function). This is all the labels including the ones that might be too close to edge of domain
    num_features - Total number of features accross datasets
    features_per frame - Number of features identified in each frame
    
    '''
    import numpy as np
    from scipy.ndimage.measurements import label,find_objects,center_of_mass
    
    uSize = S.shape
    
    if S.ndim == 3:
        str_3D=np.array([[[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]],

       [[0, 1, 0],
        [1, 1, 1],
        [0, 1, 0]],

       [[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]]], dtype='uint8')
        #str_3D = str_3D.transpose(2,1,0)

        labeled_array, num_features = label(S.transpose(2,1,0),str_3D)
        labeled_array = labeled_array.transpose(2,1,0)
    else:
        labeled_array, num_features = label(S)
            
    #print(np.unique(labeled_array))
    #print(np.unique(labeled_array[:,:,0]))
    #print(labeled_array.shape)
    
    print('There are ', num_features, ' features identified')
    
    if Thresh is not None:
        loc = find_objects(labeled_array)
        labeled_array_out = labeled_array.copy()
        
        counts = np.bincount(labeled_array.ravel())
        
        ind = np.where(counts>Thresh)[0][1:]
        mask = np.in1d(labeled_array.ravel(), ind).reshape(labeled_array.shape)
        labeled_array_out[~mask] = 0
        
        [_, labeled_array_out] = np.unique(labeled_array_out,return_inverse=True)
        labeled_array_out = labeled_array_out.reshape(labeled_array.shape)
        
        num_features_out = len(ind)
        
        print('A total of ', num_features_out, ' are larger than the threshold size')
    else:
        labeled_array_out = labeled_array
        num_features_out = num_features
        
            
    features_per_frame = np.zeros(uSize[2],dtype=int);
    cent = [];
    for i in range(uSize[2]):
        features_per_frame[i] = len(np.unique(labeled_array_out[:,:,i])[1:])
        cent.append(center_of_mass(S[:,:,i],labeled_array_out[:,:,i],np.unique(labeled_array_out[:,:,i])[1:]))
        
    #Round center locations to nearest index
    for i in range(len(cent)):
        for j in range(len(cent[i])):
            cent[i][j] = (int(round(cent[i][j][0])), int(round(cent[i][j][1])))
    
    #Remove all centers too close to edge of domain
    if EdgeBound is not None:
        newCent = []
        for i in range(len(cent)):
            newCent.append([])
            features_per_frame[i] = 0
            for j in range(len(cent[i])):
                if (cent[i][j][0]>EdgeBound-1 and cent[i][j][0]<uSize[0]-EdgeBound) and (cent[i][j][1]>EdgeBound-1 and cent[i][j][1] <uSize[1]-EdgeBound):
                    newCent[i].append(cent[i][j])
                    features_per_frame[i]+=1
        num_features_out = sum(features_per_frame)
        cent = newCent
        
        print('Of these', num_features_out, ' are far enough away from edge of domain')

    return [num_features_out, features_per_frame, labeled_array_out, cent]
示例#45
0
import sys
import os

from PIL import Image, ImageFont, ImageDraw
from matplotlib.pyplot import imshow
import numpy as np
from scipy.ndimage.measurements import center_of_mass

image = Image.new("L", (80, 80), color=(1))
draw = ImageDraw.Draw(image)

path = "data/train/wt004.ttf"
#path = "data/train/NotoSansCJKtc-Light.otf"
font = ImageFont.truetype(path, 64)

#w, h = draw.textsize("的", font=font)
#draw.text((40-w/2, 40-h/2), "的", font=font)

draw.text((0, 10), "的", (255), font=font)
print(center_of_mass(np.array(image)))

image.show()
示例#46
0
psf_partial_coh = abs(psf_partial_coh) / abs(psf_partial_coh).max()
min_error_idx = np.unravel_index(error.argmin(), shape=(rl_iterations, ))[0]

peaks, _ = find_peaks(-1 * error)
if peaks.size == 1 and peaks[0] == rl_iterations - 1:
    print("no local minimum for this number of iterations")
else:
    print(f"error local minima at iterations {peaks}")
print(f"min error={error.min():.6f} at iteration {min_error_idx}\n")

###############################################
# plot the retrieved psf and the error metric #
###############################################
if center_method == "com":
    psf_cen = list(
        map(lambda x: int(np.rint(x)), center_of_mass(psf_partial_coh)))
else:  # 'max'
    psf_cen = list(
        map(
            int,
            np.unravel_index(psf_partial_coh.argmax(),
                             shape=psf_partial_coh.shape),
        ))

fig, _, _ = gu.multislices_plot(
    psf_partial_coh,
    scale="linear",
    sum_frames=False,
    title="psf",
    reciprocal_space=False,
    is_orthogonal=True,
示例#47
0
def track_location(
    video_path,
    ref_frame,
    thresh=99,
    start_frame=0,
    stop_frame=None,
    crop_interactive=None,
    crop_cmin=None,
    crop_cmax=None,
    crop_rmin=None,
    crop_rmax=None,
):
    """
    Track the location of the largest object in the frame.

    Tracking is performed by a method involving subtracting a reference frame from each frame and
    applying a threshold.

    Args:
        video_path (str): Path to the video
        ref_frame (arraylike): The reference frame to use. Can be generated from mfreeze.locolib.reference_create
        thresh (float): A value between 0 and 100. Change this value if the location parameter is performing poorly.
        start_frame (int): The first frame to use.
        stop_frame (int): The final frame to use. Defaults to the last frame.
        crop_interactive (holoviews.streams.BoxEdit): Holoviews stream object to use if using the interactive cropping
                                                      functionality. This can be obtained from the mfreeze.video.crop
                                                      function.
        crop_cmin (int): Optional value for manual cropping. Specifies minimum column value for each frame.
        crop_cmax (int): Optional value for manual cropping. Specifies maximum column value for each frame.
        crop_rmin (int): Optional value for manual cropping. Specifies minimum row value for each frame.
        crop_rmax (int): Optional value for manual cropping. Specifies maximum row values for each frame.
    Returns:
        The estimated position of the tracked object. A (n_frames, 2) numpy array with rows corresponding to the
        row and column position of the mouse for a given frame.
    """

    cap = cv2.VideoCapture(video_path)
    stop_frame = (int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
                  if stop_frame is None else stop_frame)
    num_frames = stop_frame - start_frame
    cap.set(cv2.CAP_PROP_POS_FRAMES, start_frame)
    _, frame_old = cap.read()
    frame_old = cv2.cvtColor(frame_old, cv2.COLOR_BGR2GRAY)
    frame_nrow, frame_ncol = frame_old.shape
    using_crop, crop_settings = _parse_crop_settings(
        frame_nrow,
        frame_ncol,
        crop_interactive,
        crop_cmin,
        crop_cmax,
        crop_rmin,
        crop_rmax,
    )
    if using_crop:
        frame_old = _crop_frame(frame_old, *crop_settings)

    x_y = np.empty((num_frames, 2)).astype("uint16")

    for i in range(num_frames - 1):
        frame_present, frame_new = cap.read()
        if frame_present:
            frame_new = cv2.cvtColor(frame_new, cv2.COLOR_BGR2GRAY)
            if using_crop:
                frame_new = _crop_frame(frame_new, *crop_settings)
            diff = cv2.absdiff(ref_frame, frame_new)
            diff[diff < np.percentile(diff, thresh)] = 0
            x_y[i, :] = center_of_mass(diff)
    return x_y
示例#48
0
def gen_instance_hv_map(ann, crop_shape):
    """Input annotation must be of original shape.
    
    The map is calculated only for instances within the crop portion
    but based on the original shape in original image.

    Perform following operation:
    Obtain the horizontal and vertical distance maps for each
    nuclear instance.

    """
    orig_ann = ann.copy()  # instance ID map
    fixed_ann = fix_mirror_padding(orig_ann)
    # re-cropping with fixed instance id map
    crop_ann = cropping_center(fixed_ann, crop_shape)
    # TODO: deal with 1 label warning
    crop_ann = morph.remove_small_objects(crop_ann, min_size=30)

    x_map = np.zeros(orig_ann.shape[:2], dtype=np.float32)
    y_map = np.zeros(orig_ann.shape[:2], dtype=np.float32)

    inst_list = list(np.unique(crop_ann))
    inst_list.remove(0)  # 0 is background
    for inst_id in inst_list:
        inst_map = np.array(fixed_ann == inst_id, np.uint8)
        inst_box = get_bounding_box(inst_map)

        # expand the box by 2px
        # Because we first pad the ann at line 207, the bboxes
        # will remain valid after expansion
        inst_box[0] -= 2
        inst_box[2] -= 2
        inst_box[1] += 2
        inst_box[3] += 2

        inst_map = inst_map[inst_box[0]:inst_box[1], inst_box[2]:inst_box[3]]

        if inst_map.shape[0] < 2 or inst_map.shape[1] < 2:
            continue

        # instance center of mass, rounded to nearest pixel
        inst_com = list(measurements.center_of_mass(inst_map))

        inst_com[0] = int(inst_com[0] + 0.5)
        inst_com[1] = int(inst_com[1] + 0.5)

        inst_x_range = np.arange(1, inst_map.shape[1] + 1)
        inst_y_range = np.arange(1, inst_map.shape[0] + 1)
        # shifting center of pixels grid to instance center of mass
        inst_x_range -= inst_com[1]
        inst_y_range -= inst_com[0]

        inst_x, inst_y = np.meshgrid(inst_x_range, inst_y_range)

        # remove coord outside of instance
        inst_x[inst_map == 0] = 0
        inst_y[inst_map == 0] = 0
        inst_x = inst_x.astype("float32")
        inst_y = inst_y.astype("float32")

        # normalize min into -1 scale
        if np.min(inst_x) < 0:
            inst_x[inst_x < 0] /= -np.amin(inst_x[inst_x < 0])
        if np.min(inst_y) < 0:
            inst_y[inst_y < 0] /= -np.amin(inst_y[inst_y < 0])
        # normalize max into +1 scale
        if np.max(inst_x) > 0:
            inst_x[inst_x > 0] /= np.amax(inst_x[inst_x > 0])
        if np.max(inst_y) > 0:
            inst_y[inst_y > 0] /= np.amax(inst_y[inst_y > 0])

        ####
        x_map_box = x_map[inst_box[0]:inst_box[1], inst_box[2]:inst_box[3]]
        x_map_box[inst_map > 0] = inst_x[inst_map > 0]

        y_map_box = y_map[inst_box[0]:inst_box[1], inst_box[2]:inst_box[3]]
        y_map_box[inst_map > 0] = inst_y[inst_map > 0]

    hv_map = np.dstack([x_map, y_map])
    return hv_map
示例#49
0
def savgol_iaf(raw, picks=None,  # noqa: C901
               fmin=None, fmax=None,
               resolution=0.25,
               average=True,
               ax=None,
               window_length=11, polyorder=5,
               pink_max_r2=0.9):
    """Estimate individual alpha frequency (IAF).

    Parameters
    ----------
    raw : instance of Raw
        The raw data to do these estimations on.
    picks : array-like of int | None
        List of channels to use.
    fmin : int | None
        Lower bound of alpha frequency band. If None, it will be
        empirically estimated using a polynomial fitting method to
        determine the edges of the central parabolic peak density,
        with assumed center of 10 Hz.
    fmax : int | None
        Upper bound of alpha frequency band. If None, it will be
        empirically estimated using a polynomial fitting method to
        determine the edges of the central parabolic peak density,
        with assumed center of 10 Hz.
    resolution : float
        The resolution in the frequency domain for calculating the PSD.
    average : bool
        Whether to average the PSD estimates across channels or provide
        a separate estimate for each channel. Currently, only True is
        supported.
    ax : instance of matplotlib Axes | None | False
        Axes to plot PSD analysis into. If None, axes will be created
        (and plot not shown by default). If False, no plotting will be done.
    window_length : int
        Window length in samples to use for Savitzky-Golay smoothing of
        PSD when estimating IAF.
    polyorder : int
        Polynomial order to use for Savitzky-Golay smoothing of
        PSD when estimating IAF.
    pink_max_r2 : float
        Maximum R^2 allowed when comparing the PSD distribution to the
        pink noise 1/f distribution on the range 1 to 30 Hz.
        If this threshold is exceeded, then IAF is assumed unclear and
        None is returned for both PAF and CoG.

    Returns
    -------
    IafEst : instance of ``collections.namedtuple`` called IAFEstimate

         Named tuple with fields for the peak alpha frequency (PAF),
         alpha center of gravity (CoG), and the bounds of the alpha band
         (as a tuple).

    Notes
    -----
    Based on method developed by
    `Andrew Corcoran <https://zenodo.org/badge/latestdoi/80904585>`_.
    In addition to appropriate software citation (Zenodo DOI or
    git commit), please cite:

        Corcoran, A. W., Alday, P. M., Schlesewsky, M., &
        Bornkessel-Schlesewsky, I. (2018). Toward a reliable, automated method
        of individual alpha frequency (IAF) quantification. Psychophysiology,
        e13064. doi:10.1111/psyp.13064
    """
    n_fft = int(raw.info['sfreq'] / resolution)
    psd, freqs = mne.time_frequency.psd_welch(raw, picks=picks,
                                              n_fft=n_fft, fmin=1.,
                                              fmax=30.)
    if ax is None:
        fig = plt.figure()  # noqa: F841
        ax = plt.gca()

    if average:
        psd = np.mean(psd, axis=0)

    if fmin is None or fmax is None:
        if fmin is None:
            fmin_bound = 5
        else:
            fmin_bound = fmin

        if fmax is None:
            fmax_bound = 15
        else:
            fmax_bound = fmax

        alpha_search = np.logical_and(freqs >= fmin_bound,
                                      freqs <= fmax_bound)
        freqs_search = freqs[alpha_search]
        psd_search = savgol_filter(psd[alpha_search],
                                   window_length=psd[alpha_search].shape[0],
                                   polyorder=10)
        # argrel min returns a tuple, so we flatten that with [0]
        # then we get the last element of the resulting array with [-1]
        # which is the minimum closest to the 'median' alpha of 10 Hz
        if fmin is None:
            try:
                left_min = argrelmin(psd_search[freqs_search < 10])[0][-1]
                fmin = freqs_search[freqs_search < 10][left_min]
            except IndexError:
                raise ValueError("Unable to automatically determine lower end  of alpha band.")   # noqa: 501
        if fmax is None:
            # here we want the first element of the array which is closest to
            # the 'median' alpha of 10 Hz
            try:
                right_min = argrelmin(psd_search[freqs_search > 10])[0][0]
                fmax = freqs_search[freqs_search > 10][right_min]
            except IndexError:
                raise ValueError("Unable to automatically determine upper end of alpha band.")   # noqa: 501
    psd_smooth = savgol_filter(psd,
                               window_length=window_length,
                               polyorder=polyorder)
    alpha_band = np.logical_and(freqs >= fmin, freqs <= fmax)

    slope, intercept, r, p, se = stats.linregress(np.log(freqs),
                                                  np.log(psd_smooth))
    if r**2 > pink_max_r2:
        paf = None
        cog = None
    else:
        paf_idx = np.argmax(psd_smooth[alpha_band])
        paf = freqs[alpha_band][paf_idx]

        cog_idx = center_of_mass(psd_smooth[alpha_band])
        try:
            cog_idx = int(np.round(cog_idx[0]))
            cog = freqs[alpha_band][cog_idx]
        except ValueError:
            cog = None
            # set PAF to None as well, because this is a pathological case
            paf = None

    if ax:
        plt_psd, = ax.plot(freqs, psd, label="Raw PSD")
        plt_smooth, = ax.plot(freqs, psd_smooth, label="Smoothed PSD")
        plt_pink, = ax.plot(freqs,
                            np.exp(slope * np.log(freqs) + intercept),
                            label='$1/f$ fit ($R^2={:0.2}$)'.format(r**2))
        try:
            plt_search, = ax.plot(freqs_search, psd_search,
                                  label='Alpha-band Search Parabola')
            ax.legend(handles=[plt_psd, plt_smooth, plt_search, plt_pink])
        except UnboundLocalError:
            # this happens when the user fully specified an alpha band
            ax.legend(handles=[plt_psd, plt_smooth, plt_pink])

        ax.set_ylabel("PSD")
        ax.set_xlabel("Hz")

    return IafEst(paf, cog, (fmin, fmax))
示例#50
0
def store_preloaded_hdf5_file(
        data_directories,
        output_filepath,
        modalities=['FLAIR_pp.nii.gz', 'T1post_pp.nii.gz'],
        label='full_edemamask_pp.nii.gz',
        verbose=True,
        levels=[4, 8, 16, 32, 64, 128],
        boundary_padding=10,
        max_dimension=64,
        samples_per_patient=100,
        preload_levels=False,
        wholevolume=False):

    patient_vols = []
    for directory in data_directories:
        patients = glob.glob(os.path.join(directory, '*/'))
        for patient in patients:
            single_patient_vols = []
            for modality in modalities + [label]:
                if modality is None:
                    continue
                single_patient_vols += [
                    glob.glob(os.path.join(patient, modality))[0]
                ]
            patient_vols += [single_patient_vols]

    if wholevolume:
        num_cases = len(patient_vols)
    else:
        num_cases = len(modalities) * len(patient_vols)

    hdf5_file = tables.open_file(output_filepath, mode='w')
    filters = tables.Filters(complevel=5, complib='blosc')
    hdf5_file.create_earray(hdf5_file.root,
                            'imagenames',
                            tables.StringAtom(256),
                            shape=(0, 1),
                            filters=filters,
                            expectedrows=num_cases)

    # If we want to pre-store different levels...
    if preload_levels:
        for dimension in levels:
            data_shape = (0, dimension + boundary_padding,
                          dimension + boundary_padding,
                          dimension + boundary_padding, 2)
            hdf5_file.create_earray(hdf5_file.root,
                                    'data_' + str(dimension),
                                    tables.Float32Atom(),
                                    shape=data_shape,
                                    filters=filters,
                                    expectedrows=num_cases)
    else:
        # If we don't.
        if wholevolume:
            data_shape = (0, 200, 200, 200, len(modalities))
        else:
            data_shape = (0, max_dimension + boundary_padding,
                          max_dimension + boundary_padding,
                          max_dimension + boundary_padding, len(modalities))
        print data_shape
        hdf5_file.create_earray(hdf5_file.root,
                                'data',
                                tables.Float32Atom(),
                                shape=data_shape,
                                filters=filters,
                                expectedrows=num_cases)

    for p_idx, single_patient_vols in enumerate(patient_vols):

        hdf5_file.root.imagenames.append(
            np.array(os.path.basename(os.path.dirname(
                single_patient_vols[0])))[np.newaxis][np.newaxis])
        print os.path.basename(os.path.dirname(single_patient_vols[0]))

        if label is not None:
            # Find tumor label center of mass
            label = single_patient_vols[-1]
            label_numpy = convert_input_2_numpy(label)
            label_center = [int(x) for x in center_of_mass(label_numpy)]

            # Load volumes,
            volumes = np.stack([
                convert_input_2_numpy(vol) for vol in single_patient_vols[:-1]
            ],
                               axis=3)

            # pad if necessary, using black magic
            pad_dims = []
            radius = (max_dimension + boundary_padding) / 2
            for idx, dim in enumerate(volumes.shape[:-1]):
                padding = (-1 * min(0, label_center[idx] - radius),
                           -1 * min(0, dim - (label_center[idx] + radius)))
                pad_dims += [padding]
            pad_dims += [(0, 0)]
            print pad_dims
            volumes = np.pad(volumes, pad_dims, mode='constant')

            # and subsample, with more black magic ;)
            print label_center
            label_center = [
                x + pad_dims[i][0] for i, x in enumerate(label_center)
            ]
            print label_center
            print volumes.shape
            patch = volumes[label_center[0] - radius:label_center[0] + radius,
                            label_center[1] - radius:label_center[1] + radius,
                            label_center[2] - radius:label_center[2] +
                            radius, :]
            print patch.shape

            # Add to HDF5
            getattr(hdf5_file.root, 'data').append(patch[np.newaxis])

            save_numpy_2_nifti(
                patch[..., 1], single_patient_vols[0],
                os.path.join(os.path.dirname(single_patient_vols[0]),
                             'gan_patch.nii.gz'))

        elif wholevolume:

            # Load volumes,
            volumes = np.stack(
                [convert_input_2_numpy(vol) for vol in single_patient_vols],
                axis=3)

            # Crop volumes
            volumes = crop2(volumes)

            large = False

            # Skip strangely processed volumes
            for dim in volumes.shape:
                if dim > 200:
                    large = True

            if large:
                continue

            same_size_volume = np.zeros((200, 200, 200, len(modalities)))
            same_size_volume[0:volumes.shape[0], 0:volumes.shape[1],
                             0:volumes.shape[2], :] = volumes

            # Add to HDF5
            getattr(hdf5_file.root,
                    'data').append(same_size_volume[np.newaxis])

        else:

            # Generic MRI patching goes on here..

            continue

            if verbose:
                print 'Processed...', os.path.basename(
                    os.path.dirname(single_patient_vols[0])), 'idx', p_idx

        # except KeyboardInterrupt:
        #     raise
        # except:
        #     print 'ERROR converting', filepath, 'at dimension', dimension

    hdf5_file.close()

    return
示例#51
0
def deep_segmentation_spinalcord(im_image, contrast_type, ctr_algo='cnn', ctr_file=None, brain_bool=True,
                                 kernel_size='2d', threshold_seg=None, remove_temp_files=1, verbose=1):
    """
    Main pipeline for CNN-based segmentation of the spinal cord.

    :param im_image:
    :param contrast_type: {'t1', 't2', t2s', 'dwi'}
    :param ctr_algo:
    :param ctr_file:
    :param brain_bool:
    :param kernel_size:
    :param threshold_seg: Binarization threshold (between 0 and 1) to apply to the segmentation prediction. Set to -1
        for no binarization (i.e. soft segmentation output)
    :param remove_temp_files:
    :param verbose:
    :return:
    """
    if threshold_seg is None:
        threshold_seg = THR_DEEPSEG[contrast_type]

    # Display stuff
    logger.info("Config deepseg_sc:")
    logger.info("  Centerline algorithm: {}".format(ctr_algo))
    logger.info("  Brain in image: {}".format(brain_bool))
    logger.info("  Kernel dimension: {}".format(kernel_size))
    logger.info("  Contrast: {}".format(contrast_type))
    logger.info("  Threshold: {}".format(threshold_seg))

    # create temporary folder with intermediate results
    tmp_folder = sct.TempFolder(verbose=verbose)
    tmp_folder_path = tmp_folder.get_path()
    if ctr_algo == 'file':  # if the ctr_file is provided
        tmp_folder.copy_from(ctr_file)
        file_ctr = os.path.basename(ctr_file)
    else:
        file_ctr = None
    tmp_folder.chdir()

    # re-orient image to RPI
    logger.info("Reorient the image to RPI, if necessary...")
    original_orientation = im_image.orientation
    # fname_orient = 'image_in_RPI.nii'
    im_image.change_orientation('RPI')

    # Resample image to 0.5mm in plane
    im_image_res = \
        resampling.resample_nib(im_image, new_size=[0.5, 0.5, im_image.dim[6]], new_size_type='mm', interpolation='linear')

    fname_orient = 'image_in_RPI_res.nii'
    im_image_res.save(fname_orient)

    # find the spinal cord centerline - execute OptiC binary
    logger.info("Finding the spinal cord centerline...")
    _, im_ctl, im_labels_viewer = find_centerline(algo=ctr_algo,
                                                    image_fname=fname_orient,
                                                    contrast_type=contrast_type,
                                                    brain_bool=brain_bool,
                                                    folder_output=tmp_folder_path,
                                                    remove_temp_files=remove_temp_files,
                                                    centerline_fname=file_ctr)

    if ctr_algo == 'file':
        im_ctl = \
            resampling.resample_nib(im_ctl, new_size=[0.5, 0.5, im_image.dim[6]], new_size_type='mm', interpolation='linear')

    # crop image around the spinal cord centerline
    logger.info("Cropping the image around the spinal cord...")
    crop_size = 96 if (kernel_size == '3d' and contrast_type == 't2s') else 64
    X_CROP_LST, Y_CROP_LST, Z_CROP_LST, im_crop_nii = crop_image_around_centerline(im_in=im_image_res,
                                                                                   ctr_in=im_ctl,
                                                                                   crop_size=crop_size)

    # normalize the intensity of the images
    logger.info("Normalizing the intensity...")
    im_norm_in = apply_intensity_normalization(im_in=im_crop_nii)
    del im_crop_nii

    if kernel_size == '2d':
        # segment data using 2D convolutions
        logger.info("Segmenting the spinal cord using deep learning on 2D patches...")
        segmentation_model_fname = \
            os.path.join(sct.__sct_dir__, 'data', 'deepseg_sc_models', '{}_sc.h5'.format(contrast_type))
        seg_crop = segment_2d(model_fname=segmentation_model_fname,
                              contrast_type=contrast_type,
                              input_size=(crop_size, crop_size),
                              im_in=im_norm_in)
    elif kernel_size == '3d':
        # segment data using 3D convolutions
        logger.info("Segmenting the spinal cord using deep learning on 3D patches...")
        segmentation_model_fname = \
            os.path.join(sct.__sct_dir__, 'data', 'deepseg_sc_models', '{}_sc_3D.h5'.format(contrast_type))
        seg_crop = segment_3d(model_fname=segmentation_model_fname,
                              contrast_type=contrast_type,
                              im_in=im_norm_in)

    # Postprocessing
    seg_crop_postproc = np.zeros_like(seg_crop)
    x_cOm, y_cOm = None, None
    for zz in range(im_norm_in.dim[2]):
        # Fill holes (only for binary segmentations)
        if threshold_seg >= 0:
            pred_seg_th = fill_holes_2d((seg_crop[:, :, zz] > threshold_seg).astype(int))
            pred_seg_pp = keep_largest_object(pred_seg_th, x_cOm, y_cOm)
            # Update center of mass for slice i+1
            if 1 in pred_seg_pp:
                x_cOm, y_cOm = center_of_mass(pred_seg_pp)
                x_cOm, y_cOm = np.round(x_cOm), np.round(y_cOm)
        else:
            # If soft segmentation, do nothing
            pred_seg_pp = seg_crop[:, :, zz]

        seg_crop_postproc[:, :, zz] = pred_seg_pp  # dtype is float32

    # reconstruct the segmentation from the crop data
    logger.info("Reassembling the image...")
    im_seg = uncrop_image(ref_in=im_image_res,
                          data_crop=seg_crop_postproc,
                          x_crop_lst=X_CROP_LST,
                          y_crop_lst=Y_CROP_LST,
                          z_crop_lst=Z_CROP_LST)
    # seg_uncrop_nii.save(sct.add_suffix(fname_res, '_seg'))  # for debugging
    del seg_crop, seg_crop_postproc, im_norm_in

    # resample to initial resolution
    logger.info("Resampling the segmentation to the native image resolution using linear interpolation...")
    im_seg_r = resampling.resample_nib(im_seg, image_dest=im_image, interpolation='linear')

    if ctr_algo == 'viewer':  # for debugging
        im_labels_viewer.save(sct.add_suffix(fname_orient, '_labels-viewer'))

    # Binarize the resampled image (except for soft segmentation, defined by threshold_seg=-1)
    if threshold_seg >= 0:
        logger.info("Binarizing the resampled segmentation...")
        im_seg_r.data = (im_seg_r.data > 0.5).astype(np.uint8)

    # post processing step to z_regularized
    im_seg_r_postproc = post_processing_volume_wise(im_seg_r)

    # Change data type. By default, dtype is float32
    if threshold_seg >= 0:
        im_seg_r_postproc.change_type(np.uint8)

    tmp_folder.chdir_undo()

    # remove temporary files
    if remove_temp_files:
        logger.info("Remove temporary files...")
        tmp_folder.cleanup()

    # reorient to initial orientation
    im_seg_r_postproc.change_orientation(original_orientation)

    # copy q/sform from input image to output segmentation
    im_seg.copy_qform_from_ref(im_image)

    return im_seg_r_postproc, im_image_res, im_seg.change_orientation('RPI')
示例#52
0
def Case5(AvgFlux, X,Y,Spacing=1):
    Spacing = int(Spacing)
    Xint, Yint = [int(round(X,0)), int(round(Y,0))]
    BkgVal = np.median(AvgFlux)
    XValues = np.arange(Xint-Spacing,Xint+Spacing+1,1)
    YValues = np.arange(Yint-Spacing,Yint+Spacing+1,1)

    ReferenceValue = 0

    Dist_tolerance = 0.75
    for i,j in list(itertools.product(XValues,YValues)):
        try:
            TempAper2_2 = np.zeros((len(AvgFlux),len(AvgFlux[0])))
            TempAper2_2[i:i+2, j:j+2] = 1
            Num = np.sum(TempAper2_2)
            Signal = np.sum(AvgFlux*TempAper2_2)-Num*BkgVal
            Y_Cen, X_Cen = measurements.center_of_mass(AvgFlux*TempAper2_2)
            Distance = np.sqrt((X- X_Cen)**2+(Y- Y_Cen)**2)
            if Distance<Dist_tolerance:
                Value2_2 = Signal/np.sqrt(Signal+ (Num+1)*BkgVal)
            else:
                Value2_2 = 1
        except:
            Value2_2 = 1

        try:
            TempAper2_3 = np.zeros(len(AvgFlux[0])*len(AvgFlux)).reshape(len(AvgFlux),len(AvgFlux[0]))
            TempAper2_3[i:i+2, j:j+3] = 1
            Num = np.sum(TempAper2_3)
            Signal = np.sum(AvgFlux*TempAper2_3)-Num*BkgVal
            Y_Cen, X_Cen = measurements.center_of_mass(AvgFlux*TempAper2_3)
            Distance = np.sqrt((X- X_Cen)**2+(Y- Y_Cen)**2)
            if Distance<Dist_tolerance:
                Value2_3 = Signal/np.sqrt(Signal+(Num+1)*BkgVal)
            else:
                Value2_3 = 2
        except:
            Value2_3 = 2

        try:
            TempAper3_2 = np.zeros(len(AvgFlux[0])*len(AvgFlux)).reshape(len(AvgFlux),len(AvgFlux[0]))
            TempAper3_2[i:i+3, j:j+2] = 1
            Num = np.sum(TempAper3_2)
            Value3_2 = np.sum(AvgFlux*TempAper3_2)-Num*BkgVal
            Y_Cen, X_Cen = measurements.center_of_mass(AvgFlux*TempAper3_2)
            Distance = np.sqrt((X- X_Cen)**2+(Y- Y_Cen)**2)
            if Distance<Dist_tolerance:
                Value3_2 = Signal/np.sqrt(Signal+(Num+1)*BkgVal)
            else:
                Value3_2 = 3
        except:
            Value3_2 = 3

        try:
            TempAper3_3 = np.zeros(len(AvgFlux[0])*len(AvgFlux)).reshape(len(AvgFlux),len(AvgFlux[0]))
            TempAper3_3[i:i+3, j:j+3] = 1
            Num = np.sum(TempAper3_3)
            Signal = np.sum(AvgFlux*TempAper3_3)-Num*BkgVal
            Y_Cen, X_Cen = measurements.center_of_mass(AvgFlux*TempAper3_3)
            Distance = np.sqrt((X- X_Cen)**2+(Y- Y_Cen)**2)
            if Distance<Dist_tolerance:
                Value3_3 = Signal/np.sqrt(Signal+(Num+1)*BkgVal)
            else:
                Value3_3 = 4
        except:
            Value3_3 = 4

        #star like shaped with five selection
        try:
            TempAper_Star = np.zeros(len(AvgFlux[0])*len(AvgFlux)).reshape(len(AvgFlux),len(AvgFlux[0]))
            TempAper_Star[i+1:i+2, j:j+3] = 1
            TempAper_Star[i:i+3, j+1:j+2] = 1
            Num = np.sum(TempAper_Star)
            Signal = np.sum(AvgFlux*TempAper_Star)-Num*BkgVal
            Y_Cen, X_Cen = measurements.center_of_mass(AvgFlux*TempAper_Star)
            Distance = np.sqrt((X- X_Cen)**2+(Y- Y_Cen)**2)
            if Distance<Dist_tolerance:
                Value_Star = Signal/np.sqrt(Signal+(Num+1)*BkgVal)
            else:
                Value_Star = 5
        except:
            Value_Star = 5

        #See which one is the best fit
        Values = np.array([Value2_2, Value2_3, Value3_2, Value3_3, Value_Star])
        MaxValue = max(Values)
        if MaxValue>ReferenceValue:
            ReferenceValue = MaxValue
            RefX, RefY = [i,j]
            TypeAperture = np.where(MaxValue == Values)[0][0]

    if ReferenceValue<7:
        #Find suitable 4 by 4 aperture based on distance
        print "-"*50
        print "Failed to find a good aperture"
        print "-"*50

        #Aperture just based on the distance
        RefX, RefY = [Xint, Yint]
        DistanceRef = 5
        for i,j in list(itertools.product(XValues,YValues)):
          try:
            TempAper2_2 = np.zeros(len(AvgFlux[0])*len(AvgFlux)).reshape(len(AvgFlux),len(AvgFlux[0]))
            TempAper2_2[i:i+2, j:j+2] = 1
            Y_Cen, X_Cen = measurements.center_of_mass(AvgFlux*TempAper2_2)
            Distance = np.sqrt((X- X_Cen)**2+(Y- Y_Cen)**2)
            if Distance<DistanceRef:
                RefX,RefY = [i,j]
                DistanceRef = Distance
          except:
            pass
        TypeAperture = 0


    Aperture = np.zeros(len(AvgFlux[0])*len(AvgFlux)).reshape(len(AvgFlux),len(AvgFlux[0]))
    i,j = [RefX, RefY]
    if TypeAperture == 0:
        Aperture[i:i+2,j:j+2] = 1
    elif TypeAperture == 1:
        Aperture[i:i+2, j:j+3] = 1
    elif TypeAperture == 2:
        Aperture[i:i+3, j:j+2] = 1
    elif TypeAperture == 3:
        Aperture[i:i+3, j:j+3] = 1
    elif TypeAperture == 4:
        Aperture[i+1:i+2, j:j+3] = 1
        Aperture[i:i+3, j+1:j+2] = 1
    else:
        raise Exception('Error finding a good aperture')
    return Aperture
示例#53
0
def fit_nema_2008_cylinder_profiles(vol, 
                                    voxsize,
                                    Rrod_init  = [2.5,2,1.5,1,0.5],
                                    fwhm_init  = 1.5,
                                    S_init     = 1,
                                    fix_S      = True,
                                    fix_R      = False,
                                    fix_fwhm   = False,
                                    nrods      = 4,
                                    phantom    = 'standard'):
  """ Fit the radial profiles of the rods in a nema 2008 small animal PET phantom

  Parameters
  ----------
  vol : 3D numpy float array
    containing the image

  voxsize : 3 element 1D numpy array
    containing the voxel size

  Rrod_init : list or 1D numpy array of floats, optional
    containing the initial values of the rod radii

  S_init, fwhm_init: float, optional
    initial values for the signal and the FWHM in the fit

  fix_S, fix_R, fix_fwhm : bool, optional
    whether to keep the initial values of signal, radius and FWHM fixed during the fix

  nrods: int, optional
    number of rods to fit

  phantom : string
    phantom version ('standard' or 'mini')

  Returns
  -------
  a list of lmfit fit results

  Note
  ----

  The axial direction should be the right most direction in the 3D numpy array.
  The slices containing the rods are found automatically and summed.
  In the summed image, all rods (disks) are segmented followed by a fit
  of the radial profile.
  """
  roi_vol = nema_2008_small_animal_pet_rois(vol, voxsize, phantom = phantom)
  
  rod_bbox = find_objects(roi_vol==4)
  
  # find the rods in the summed image
  sum_img = vol[:,:,rod_bbox[0][2].start:rod_bbox[0][2].stop].mean(2)
  
  label_img, nlab = label(sum_img > 0.1*sum_img.max())
  labels = np.arange(1,nlab+1)
  # sort the labels according to volume
  npix   = labeled_comprehension(sum_img, label_img, labels, len, int, 0)
  sort_inds = npix.argsort()[::-1]
  labels    = labels[sort_inds] 
  npix      = npix[sort_inds] 
  
  #----------------------------------------------------------------------  
  ncols = 2
  nrows = int(np.ceil(nrods/ncols))
  fig, ax = py.subplots(nrows,ncols,figsize = (12,7*nrows/2), sharey = True, sharex = True)
 
  retval = []
 
  for irod in range(nrods):
    rod_bbox = find_objects(label_img == labels[irod])
   
    rod_bbox = [(slice(rod_bbox[0][0].start - 2,rod_bbox[0][0].stop + 2),
                 slice(rod_bbox[0][1].start - 2,rod_bbox[0][1].stop + 2))]
   
    rod_img = sum_img[rod_bbox[0]]
    com     = np.array(center_of_mass(rod_img))
    
    x0 = (np.arange(rod_img.shape[0]) - com[0]) * voxsize[0]
    x1 = (np.arange(rod_img.shape[1]) - com[1]) * voxsize[1]
    
    X0, X1 = np.meshgrid(x0, x1, indexing = 'ij')
    RHO    = np.sqrt(X0**2 + X1**2) 
    
    rho    = RHO.flatten()
    signal = rod_img.flatten()
    
    # sort the values according to rho
    sort_inds = rho.argsort()
    rho       = rho[sort_inds]
    signal    = signal[sort_inds]
    
    pmodel = Model(cylinder_profile)
    params = pmodel.make_params(S = S_init, R = Rrod_init[irod], fwhm = fwhm_init)

    if fix_S:
      params['S'].vary = False
    if fix_R:
      params['R'].vary = False
    if fix_fwhm:
      params['fwhm'].vary = False
    
    fitres = pmodel.fit(signal, r = rho, params = params)
    retval.append(fitres)
    fit_report = fitres.fit_report()
   
    iplot = np.unravel_index(irod, ax.shape) 
    ax[iplot].plot(rho,signal,'k.')
    
    rfit = np.linspace(0,rho.max(),100)
    ax[iplot].plot(rfit,fitres.eval(r = rfit),'r-')
    ax[iplot].text(0.99, 0.99, fit_report, fontsize = 6, transform = ax[iplot].transAxes, 
                         verticalalignment='top', horizontalalignment = 'right',
                         backgroundcolor = 'white', bbox = {'pad':0, 'facecolor':'white','lw':0})
    ax[iplot].grid()
  
  for axx in ax[-1,:]: axx.set_xlabel('R (mm)')
  for axx in ax[:,0]:  axx.set_ylabel('signal')
  
  fig.tight_layout()
  fig.show()

  return retval
def get_patches_and_vectors(I,
                            bx,
                            by,
                            bz,
                            pixel_limit=20,
                            thr=0.5,
                            floodfill=4):
    '''
    I - intensity map for detecting pores; should be normalized to quiet sun
    bx - bx data (should be Bp from sharps) type should be sunpy map
    by - by data (should be Bt from sharps) type should be sunpy map. DO NOT CHANGE SIGN OF DATA, THIS FUNCTION WILL DO IT! 
    bz - bz data (should be Br from sharps) type should be sunpy map
    pixel_limit - ignore patches that are smaller than this size
    thr - if I < thr => we assign it as pixel of interes; if data is normalized, 0.5 should work
    floodfill - in how many direction structure should perform flood fill
    https://en.wikipedia.org/wiki/Flood_fill
    
    floodfill = 4 looks in 4 direction and search structure looks like this
       [[0,1,0],
        [1,1,1],
        [0,1,0]]

    floodfill = 8 looks in 8 direction and search structure looks like this
        [[1,1,1],
         [1,1,1],
         [1,1,1]]
         
    Returns:
    
        This function returns two arrays:
        
        RETURN_MATRIX - Matrix that has data for patches center in dims [6xN] where N is number of patches.
        It is of folowing structure
        c_x[pix], c_y[pix], <Bx>[G], <By>[G], <Bz>[G], A[pixel_count]
        
        If there is no patches, this matrix is empty
        
        labeled_array - Matrix of same size as input intensity image
        if there are no patches this matrix is filled with zeros
         
    '''
    # Create masked array from I data
    if floodfill == 8:
        print("Using 8 directions search map %s" % (I.name))
        s = generate_binary_structure(2, 2)
    else:
        print("Using 4 directions search map on %s" % (I.name))
        s = generate_binary_structure(2, 1)

    X = np.ma.masked_where((I.data <= thr) & (I.data > 0), I.data)
    #LOL!
    #So, if mask is false (nothing satisfies condition), and you use structure in label
    #it will crash because its comparing structure off size [3,3] with 1D array
    #So lets handle it right here
    #And its faster at the end, we are leaving function right here
    if not X.mask.any():
        return np.zeros([]), np.zeros([I.data.shape[0], I.data.shape[1]])

    try:
        # sometimes this fails because of endianness
        # Select regions based on structures
        # labeled array is same dimension as input image
        labeled_array, num_features = label(X.mask, structure=s)
    except:
        labeled_array, num_features = label(X.mask.newbyteorder(), structure=s)

    # find how many pixel is in each patch
    regions, counts = np.unique(labeled_array, return_counts=True)

    # if pixel count for patch is smaller then pixel_limit
    # This labels of patches with small pixel count
    remove_patches = (counts < pixel_limit).nonzero()[0]
    # Set it to zero
    for i in remove_patches:
        labeled_array[labeled_array == i] = 0

    # THIS IS LAZY PROGRAMMING!!! DONT DO THIS!
    # i wanted smooth region labelin (0,1,2,3,4) not gapped (0,1,4,6,7), i could do that manually, but im lazy
    # I cant overwrite labeled_array variable because im using it later in cmass
    labeled_array1, num_features1 = label(labeled_array)
    #print(num_featurues)

    #Check again if we removed all features because of trh for region of interest
    #I tought that we are smarter than nested if/elif/else
    if num_features1 == 0:
        return np.zeros([]), np.zeros([I.data.shape[0], I.data.shape[1]])

    #######
    # lets calculate centers of patches
    # Actuall patches are marked as 1 and above, 0 is background
    elif num_features1 == 1:
        features_label = np.array([1])
    else:
        #it has to be +1 because arange(1,2,1) returns np.array([1])
        #so we are missing some data
        features_label = np.arange(1, num_features1 + 1, 1)
    cmass = center_of_mass(labeled_array, labeled_array1, features_label)
    # print(labeled_array)

    # Create placeholder matrix that has
    # cx[pix], cy[pix], <bx>[G], <by>[G], <bz>[G], A[pix_count]
    #
    #because 0 is not feature we are interested in
    #print(num_features1)
    RETURN_MATRIX = np.zeros([num_features1, 6])
    regions1, counts1 = np.unique(labeled_array1, return_counts=True)

    for pore_index in features_label:
        # valid pixels for that pore index over which we should average
        valid_pixels = np.argwhere(labeled_array1 == pore_index)
        RETURN_MATRIX[pore_index - 1][0] = cmass[pore_index - 1][1]
        RETURN_MATRIX[pore_index - 1][1] = cmass[pore_index - 1][0]
        RETURN_MATRIX[pore_index - 1][2] = np.mean(bx.data[valid_pixels[:, 0],
                                                           valid_pixels[:, 1]])
        #Note that here we are using -by because Bt = -By
        RETURN_MATRIX[pore_index -
                      1][3] = np.mean(-by.data[valid_pixels[:, 0],
                                               valid_pixels[:, 1]])
        RETURN_MATRIX[pore_index - 1][4] = np.mean(bz.data[valid_pixels[:, 0],
                                                           valid_pixels[:, 1]])
        #Pixel count
        RETURN_MATRIX[pore_index - 1][5] = counts1[pore_index]

    return RETURN_MATRIX, labeled_array1
示例#55
0
def initialize_components(Y,
                          K=30,
                          gSig=[5, 5],
                          gSiz=None,
                          ssub=1,
                          tsub=1,
                          nIter=5,
                          maxIter=5,
                          nb=1,
                          kernel=None,
                          use_hals=True,
                          normalize_init=True,
                          img=None,
                          method='greedy_roi',
                          max_iter_snmf=500,
                          alpha_snmf=10e2,
                          sigma_smooth_snmf=(.5, .5, .5),
                          perc_baseline_snmf=20,
                          options_local_NMF=None):
    """Initalize components

    This method uses a greedy approach followed by hierarchical alternative least squares (HALS) NMF.
    Optional use of spatio-temporal downsampling to boost speed.

    Parameters
    ----------
    Y: np.ndarray
         d1 x d2 [x d3] x T movie, raw data.
    K: [optional] int
        number of neurons to extract (default value: 30).
    tau: [optional] list,tuple
        standard deviation of neuron size along x and y [and z] (default value: (5,5).
    gSiz: [optional] list,tuple
        size of kernel (default 2*tau + 1).
    nIter: [optional] int
        number of iterations for shape tuning (default 5).
    maxIter: [optional] int
        number of iterations for HALS algorithm (default 5).
    ssub: [optional] int
        spatial downsampling factor recommended for large datasets (default 1, no downsampling).
    tsub: [optional] int
        temporal downsampling factor recommended for long datasets (default 1, no downsampling).
    kernel: [optional] np.ndarray
        User specified kernel for greedyROI (default None, greedy ROI searches for Gaussian shaped neurons)
    use_hals: [optional] bool
        Whether to refine components with the hals method
    normalize_init: [optional] bool
        Whether to normalize_init data before running the initialization
    img: optional [np 2d array]
        Image with which to normalize. If not present use the mean + offset 
    method: str  
        Initialization method 'greedy_roi' or 'sparse_nmf' 
    max_iter_snmf: int 
        Maximum number of sparse NMF iterations
    alpha_snmf: scalar
        Sparsity penalty

    Returns
    --------
    Ain: np.ndarray
        (d1*d2[*d3]) x K , spatial filter of each neuron.
    Cin: np.ndarray
        T x K , calcium activity of each neuron.
    center: np.ndarray
        K x 2 [or 3] , inferred center of each neuron.
    bin: np.ndarray
        (d1*d2[*d3]) x nb, initialization of spatial background.
    fin: np.ndarray
        nb x T matrix, initalization of temporal background.

    """

    if method == 'local_nmf':
        tsub_lnmf = tsub
        ssub_lnmf = ssub
        tsub = 1
        ssub = 1

    if gSiz is None:
        gSiz = 2 * np.asarray(gSig) + 1

    d, T = np.shape(Y)[:-1], np.shape(Y)[-1]
    # rescale according to downsampling factor
    gSig = np.round(np.asarray(gSig) / ssub).astype(np.int)
    gSiz = np.round(np.asarray(gSiz) / ssub).astype(np.int)

    print('Noise Normalization')
    if normalize_init is True:
        if img is None:
            img = np.mean(Y, axis=-1)
            img += np.median(img)

        Y = old_div(Y, np.reshape(img, d + (-1, ), order='F'))
        alpha_snmf /= np.mean(img)

    # spatial downsampling
    mean_val = np.mean(Y)
    if ssub != 1 or tsub != 1:
        print("Spatial Downsampling ...")
        Y_ds = downscale_local_mean(Y,
                                    tuple([ssub] * len(d) + [tsub]),
                                    cval=mean_val)
    else:
        Y_ds = Y

    print('Roi Extraction...')

    if method == 'greedy_roi':
        Ain, Cin, _, b_in, f_in = greedyROI(Y_ds,
                                            nr=K,
                                            gSig=gSig,
                                            gSiz=gSiz,
                                            nIter=nIter,
                                            kernel=kernel,
                                            nb=nb)

        if use_hals:
            print('Refining Components...')
            Ain, Cin, b_in, f_in = hals(Y_ds,
                                        Ain,
                                        Cin,
                                        b_in,
                                        f_in,
                                        maxIter=maxIter)

    elif method == 'sparse_nmf':

        Ain, Cin, _, b_in, f_in = sparseNMF(Y_ds,
                                            nr=K,
                                            nb=nb,
                                            max_iter_snmf=max_iter_snmf,
                                            alpha=alpha_snmf,
                                            sigma_smooth=sigma_smooth_snmf,
                                            remove_baseline=True,
                                            perc_baseline=perc_baseline_snmf)
#        print np.sum(Ain), np.sum(Cin)
#        print 'Refining Components...'
#        Ain, Cin, b_in, f_in = hals(Y_ds, Ain, Cin, b_in, f_in, maxIter=maxIter)
#        print np.sum(Ain), np.sum(Cin)
    elif method == 'pca_ica':

        Ain, Cin, _, b_in, f_in = ICA_PCA(Y_ds, nr = K, sigma_smooth=sigma_smooth_snmf,  truncate = 2, fun='logcosh',\
                                          max_iter=max_iter_snmf, tol=1e-10,remove_baseline=True, perc_baseline=perc_baseline_snmf, nb=nb)

    elif method == 'local_nmf':
        from SourceExtraction.CNMF4Dendrites import CNMF4Dendrites
        from SourceExtraction.AuxilaryFunctions import GetCentersData
        #Get initialization for components center
        print(Y_ds.transpose([2, 0, 1]).shape)
        if options_local_NMF is None:

            raise Exception('You need to define arguments for local NMF')

#            #Define CNMF parameters
#            mbs=[tsub_lnmf] # temporal downsampling of data in intial phase of NMF
#            ds=ssub_lnmf # spatial downsampling of data in intial phase of NMF. Ccan be an integer or a list of the size of spatial dimensions
#            TargetAreaRatio=[0.01,0.06] # target sparsity range for spatial components
#            #repeats=1 # how many repeations to run NMF algorithm
#            iters0=[5] #30 number of intial NMF iterations, in which we downsample data and add components
#            iters=20 #100 number of main NMF iterations, in which we fine tune the components on the full data
#            lam1_s=10# l1 regularization parameter initialization (for increased sparsity). If zero, we have no l1 sparsity penalty
#            bkg_per=0.1 # intialize of background shape at this percentile (over time) of video
#            sig=Y_ds.shape[:-1] # estiamte size of neuron - bounding box is 3 times this size. If larger then data, we have no bounding box.
#            MergeThreshold_activity=0.85#merge components if activity is correlated above the this threshold (and sufficiently close)
#            MergeThreshold_shapes=0.99 #merge components if activity is correlated above the this threshold (and sufficiently close)
#            Connected=True # should we constrain all spatial component to be connected?
#            SigmaMask=3  # if not [], then update masks so that they are non-zero a radius of SigmaMasks around previous non-zero support of shapes

#Get initialization for components center

#            NumCent=400 # Max number of centers to import from Group Lasso intialization - if 0, we don't run group lasso
#            cent=GetCentersData(Y_ds.transpose([2,0,1]),NumCent)
#
#            #Define CNMF parameters
#            mbs=[10] # temporal downsampling of data in intial phase of NMF
#            ds=1 # spatial downsampling of data in intial phase of NMF. Ccan be an integer or a list of the size of spatial dimensions
#            TargetAreaRatio=[0.01,0.06] # target sparsity range for spatial components
#            #repeats=1 # how many repeations to run NMF algorithm
#            iters0=[5] #30 number of intial NMF iterations, in which we downsample data and add components
#            iters=20 #100 number of main NMF iterations, in which we fine tune the components on the full data
#            lam1_s=10# l1 regularization parameter initialization (for increased sparsity). If zero, we have no l1 sparsity penalty
#            updateLambdaIntervals=2 # update sparsity parameter every updateLambdaIntervals iterations
#            addComponentsIntervals=1 # in initial NMF phase, add new component every updateLambdaIntervals*addComponentsIntervals iterations
#            updateRhoIntervals=1 # in main NMF phase, update sparsity learning speed (Rho) every updateLambdaIntervals*updateRhoIntervals iterations
#            Background_num=1 #number of background components - one of which at every repetion
#            bkg_per=0.1 # intialize of background shape at this percentile (over time) of video
#            sig=Y_ds.shape[:-1] # estiamte size of neuron - bounding box is 3 times this size. If larger then data, we have no bounding box.
#            MergeThreshold_activity=0.85#merge components if activity is correlated above the this threshold (and sufficiently close)
#            MergeThreshold_shapes=0.99 #merge components if activity is correlated above the this threshold (and sufficiently close)
#            Connected=True # should we constrain all spatial component to be connected?
#            SigmaMask=3  # if not [], then update masks so that they are non-zero a radius of SigmaMasks around previous non-zero support of shapes

#            cnmf_obj=CNMF4Dendrites(sig=sig, verbose=True,adaptBias=True,TargetAreaRatio=TargetAreaRatio,
#                     Connected=Connected, SigmaMask=SigmaMask,bkg_per=bkg_per,iters=iters,iters0=iters0, mbs=mbs,
#                     ds=ds,lam1_s=lam1_s,MergeThreshold_activity=MergeThreshold_activity,MergeThreshold_shapes=MergeThreshold_shapes)
        else:

            NumCent = options_local_NMF.pop(
                'NumCent', None
            )  # Max number of centers to import from Group Lasso intialization - if 0, we don't run group lasso
            cent = GetCentersData(Y_ds.transpose([2, 0, 1]), NumCent)
            sig = Y_ds.shape[:
                             -1]  # estiamte size of neuron - bounding box is 3 times this size. If larger then data, we have no bounding box.
            cnmf_obj = CNMF4Dendrites(sig=sig,
                                      verbose=True,
                                      adaptBias=True,
                                      **options_local_NMF)

        #Define CNMF parameters
        _, _, _ = cnmf_obj.fit(
            np.array(Y_ds.transpose([2, 0, 1]), dtype=np.float), cent)

        Ain = cnmf_obj.A
        Cin = cnmf_obj.C
        b_in = cnmf_obj.b
        f_in = cnmf_obj.f

#        Cin, _, b_in, f_in = ICA_PCA(Y_ds, nr = K, sigma_smooth=sigma_smooth_snmf,  truncate = 2, fun='logcosh',\
#                                          max_iter=max_iter_snmf, tol=1e-10,remove_baseline=True, perc_baseline=perc_baseline_snmf, nb=nb)

    else:

        print(method)
        raise Exception("Unsupported method")

    K = np.shape(Ain)[-1]
    ds = Y_ds.shape[:-1]

    Ain = np.reshape(Ain, ds + (K, ), order='F')

    if len(ds) == 2:

        Ain = resize(Ain, d + (K, ), order=1)

    else:  # resize only deals with 2D images, hence apply resize twice

        Ain = np.reshape([resize(a, d[1:] + (K, ), order=1) for a in Ain],
                         (ds[0], d[1] * d[2], K),
                         order='F')
        Ain = resize(Ain, (d[0], d[1] * d[2], K), order=1)

    Ain = np.reshape(Ain, (np.prod(d), K), order='F')

    #import pdb
    # pdb.set_trace()

    b_in = np.reshape(b_in, ds + (nb, ), order='F')

    if len(ds) == 2:
        b_in = resize(b_in, d + (nb, ), order=1)
    else:
        b_in = np.reshape([resize(b, d[1:] + (nb, ), order=1) for b in b_in],
                          (ds[0], d[1] * d[2], nb),
                          order='F')
        b_in = resize(b_in, (d[0], d[1] * d[2], nb), order=1)

    b_in = np.reshape(b_in, (np.prod(d), nb), order='F')

    Cin = resize(Cin, [K, T])

    f_in = resize(np.atleast_2d(f_in), [nb, T])
    # center = com(Ain, *d)
    center = np.asarray(
        [center_of_mass(a.reshape(d, order='F')) for a in Ain.T])

    if normalize_init is True:
        #import pdb
        # pdb.set_trace()
        Ain = Ain * np.reshape(img, (np.prod(d), -1), order='F')

        b_in = b_in * np.reshape(img, (np.prod(d), -1), order='F')
        # b_in = np.atleast_2d(b_in * img.flatten('F')) #np.reshape(img,
        # (np.prod(d), -1),order='F')
        Y = Y * np.reshape(img, d + (-1, ), order='F')

    return Ain, Cin, b_in, f_in, center
示例#56
0
                        prediction[prediction < THRESHOLD] = 0  # thresholding
                        prediction[prediction > 0] = 1
                        prediction = prediction.reshape(324, 324)

                        # localize the center of nodule
                        if np.amax(prediction) > 0:
                            centers = []
                            #erosion
                            selem = morphology.disk(1)
                            image_eroded = morphology.binary_erosion(
                                prediction, selem=selem)

                            label_im, nb_labels = ndimage.label(image_eroded)
                            for i in xrange(1, nb_labels + 1):
                                blob_i = np.where(label_im == i, 1, 0)
                                mass = center_of_mass(blob_i)
                                centers.append([mass[1], mass[0]])

                            for center in centers:
                                world_coords = voxel_2_world(
                                    np.asarray(
                                        [center[0], center[1], slice_index]),
                                    np.asarray(origin), np.asarray([1, 1, 1]))
                                resnet_coords = world_2_voxel(
                                    np.asarray(world_coords),
                                    np.asarray(origin),
                                    np.asarray(OUTPUT_SPACING))
                                resnet_coords = np.floor(resnet_coords).astype(
                                    'int16')
                                # print world_coords, resnet_coords
示例#57
0
def display_masks(anns,
                  colors,
                  im_height=448,
                  im_width=448,
                  no_display_text=False,
                  display_route=False):
    """Display annotations in image."""

    if len(anns) == 0:
        return 0
    ax = plt.gca()
    box_width = 30
    box_height = 10
    ax.set_autoscale_on(False)

    xdata = []
    ydata = []

    for i, ann in enumerate(anns):

        if display_route:
            display_txt = "%d" % (i)
        else:
            display_txt = "%d: %s. %.2f" % (i, ann['category_name'],
                                            ann['score'])

        if 'ignore' in ann:
            if ann['ignore'] == 1:
                continue
        display_txt = ann['category_name']
        if display_txt == 'motorbike':
            display_txt = 'motor'
        elif display_txt == 'bicycle':
            display_txt = 'bike'
        elif display_txt == 'dining table':
            display_txt = 'table'
        elif display_txt == 'potted plant':
            display_txt = 'plant'
        elif display_txt == 'airplane':
            display_txt = 'plane'
        if type(ann['segmentation']['counts']) == list:
            rle = mask.frPyObjects([ann['segmentation']], im_height, im_width)
        else:
            rle = [ann['segmentation']]
        m = mask.decode(rle)
        y, x = center_of_mass(m.squeeze())
        x = max(0, x - box_width)
        y = max(0, y - box_height)
        y = min(m.shape[0] - box_height, y)
        x = min(m.shape[1] - box_width, x)

        xdata.append(x)
        ydata.append(y)

        img = np.ones((m.shape[0], m.shape[1], 3))
        color_mask = np.array(colors[i]) / 255.0
        for i in range(3):
            img[:, :, i] = color_mask[i]
        ax.imshow(np.dstack((img, m * 0.5)))
        if not no_display_text:

            ax.text(x,
                    y,
                    display_txt,
                    bbox={
                        'facecolor': color_mask,
                        'alpha': 0.6
                    })

    xdata = np.array(xdata)
    ydata = np.array(ydata)

    if display_route:
        line = matplotlib.lines.Line2D(xdata, ydata, color='r', linewidth=1)
        ax = plt.subplot(111)
        ax.add_line(line)
示例#58
0
    data[np.isnan(data)] = 0
    mask[np.isnan(mask)] = 1
    # check for Inf
    mask[np.isinf(data)] = 1
    data[np.isinf(data)] = 0
    mask[np.isinf(mask)] = 1

    data[mask == 1] = 0
    if save_asint:
        data = data.astype(int)

    ####################
    # debugging plots  #
    ####################
    if debug:
        z0, y0, x0 = center_of_mass(data)
        fig, _, _ = gu.multislices_plot(data, sum_frames=False, scale='log', plot_colorbar=True, vmin=0,
                                        title='Masked data', slice_position=[int(z0), int(y0), int(x0)],
                                        is_orthogonal=not use_rawdata, reciprocal_space=True)
        plt.savefig(savedir + 'middle_frame_S' + str(scans[scan_nb]) + '_' + str(nz) + '_' + str(ny) + '_' +
                    str(nx) + binning_comment + '.png')
        if not flag_interact:
            plt.close(fig)

        fig, _, _ = gu.multislices_plot(data, sum_frames=True, scale='log', plot_colorbar=True, vmin=0, title='Masked data',
                                        is_orthogonal=not use_rawdata, reciprocal_space=True)
        plt.savefig(savedir + 'sum_S' + str(scans[scan_nb]) + '_' + str(nz) + '_' + str(ny) + '_' +
                    str(nx) + binning_comment + '.png')
        if not flag_interact:
            plt.close(fig)
示例#59
0
plt.axis('scaled')
plt.title("phase after ramp removal")
plt.pause(0.1)
####################
# remove phase offset
####################
support = np.zeros(amp.shape)
support[amp > 0.05] = 1
plt.figure()
plt.imshow(support, cmap=my_cmap)
plt.colorbar()
plt.axis('scaled')
plt.title("support used for offset removal")
plt.pause(0.1)

ycom, xcom = center_of_mass(support)
print("Mean phase:", phase[support == 1].mean(), "rad")
print("COM at (y, x): (", ',', str('{:.2f}'.format(ycom)), ',',
      str('{:.2f}'.format(xcom)), ')')
print("Phase offset at COM(amp) of:",
      str('{:.2f}'.format(phase[int(ycom), int(xcom)])), "rad")
phase = phase - phase[int(ycom), int(xcom)]

plt.figure()
plt.imshow(phase, cmap=my_cmap)
plt.colorbar()
plt.axis('scaled')
plt.title("phase after offset removal")
plt.pause(0.1)
####################
# wrap phase
示例#60
0
def giveRod(TestImage,rodfilter,penaltyfilter,\
            iters=[15,30,45,60,75,90,105,120,135,150,165,180],\
            snrthres=2.0,\
            somaFilter=None,
            somathres=0.32,
            fragRodRefine=True,\
            areaRefine=True,\
            areathres = 0.03):
    """
    Rotate the rod and pennalty filter for each angle in the iters,
    get the SNR and then threshold (snrthres), merge the detected cells at each angle and give the 
    final deteced rod cells

    The final detected cells will go through two refining processes
    For the fragRodRefine process, a soma only filter is needed, currently, we simply use the amoeboid filter
    For the areaRefine process, we request that the detected cells must have 5% of filter size (75*75*0.05)
    """
    CrPlanes = dict()

    final_results = np.zeros((TestImage.shape[0], TestImage.shape[1]))
    for i in iters:
        rotated_rod = rotate_image(rodfilter, i)
        rotated_rodp = rotate_image(penaltyfilter, i)

        # do convolution
        Cr = ndimage.convolve(TestImage, rotated_rod)
        Crp = ndimage.convolve(TestImage, rotated_rodp)
        SNR = Cr / Crp
        CrPlanes[i] = [Cr, Crp]
        rodcells = np.greater(SNR, snrthres).astype(np.float)
        final_results = np.logical_or(final_results, rodcells).astype(np.float)

    # Filtering the resutls

    labels, numofgroups = measurements.label(final_results)

    if fragRodRefine:
        #1) use the soma filter correlation plane to reduce false positive detection
        #  (fragmented rod-like cells) in which two sepearated amoeboid cells
        #  produces a false positive detection
        #   ooo   ooo    /ooo==ooo\
        #   ooo   ooo    \ooo==ooo/
        somaCrPlane = ndimage.convolve(TestImage, somaFilter)
        somaDetected = np.greater(somaCrPlane, somathres).astype(np.float)

        overlap = somaDetected * final_results

        # get the centers of the detection
        labels, nGroups = measurements.label(final_results)
        centers = measurements.center_of_mass(final_results, labels,
                                              list(range(1, nGroups + 1)))

        # check if the somaDetected overlapped with center of rod detections
        for i in range(nGroups):
            if overlap[int(centers[i][0]), int(centers[i][1])] == 0:
                final_results[labels == i + 1] = 0

    if areaRefine:
        final_results = areaRefinement(final_results)
    # 2) put an area restraint: if the detected area are too small, ignore
    #for i in range(1,nGroups+1):
    #if np.sum(final_results[labels==i])  <= 75*75*areathres:
    #final_results[labels == i] = 0.0

    return final_results, CrPlanes