Beispiel #1
0
def get_training_data(file_img, file_mask, r):
    # create mask
    input_mask = irtk.imread(file_mask)
    x_min, y_min, z_min, x_max, y_max, z_max = (input_mask == 0).bbox()

    background = irtk.zeros(input_mask.get_header(), dtype='uint8')
    background[z_min:z_max + 1, y_min:y_max + 1, x_min:x_max + 1] = 1
    background = nd.morphological_gradient(background, size=7)
    n = background[z_min + 1:z_max, y_min + 1:y_max, x_min + 1:x_max].sum()
    z = np.random.randint(low=0, high=input_mask.shape[0], size=1.25 * n)
    y = np.random.randint(low=0, high=input_mask.shape[1], size=1.25 * n)
    x = np.random.randint(low=0, high=input_mask.shape[2], size=1.25 * n)
    background[z, y, x] = 1
    background[z_min + 1:z_max, y_min + 1:y_max, x_min + 1:x_max] = 0

    foreground = (input_mask == 1).astype('uint8')

    new_mask = irtk.zeros(input_mask.get_header(), dtype='uint8')
    new_mask[foreground == 1] = 1
    new_mask[background != 0] = 2

    img = irtk.imread(file_img, dtype='float32')

    X = []
    Y = []

    for z in xrange(img.shape[0]):
        YX = np.transpose(np.nonzero(foreground[z]))
        if DEBUG:
            YX = YX[::10]
        else:
            YX = YX[::2]
        if YX.shape[0] == 0:
            continue
        patches = extract_patches2D(img[z], r, YX)
        patches = np.reshape(
            patches, (patches.shape[0], patches.shape[1] * patches.shape[2]))
        print patches.shape, YX.shape
        X.extend(patches)
        Y.extend([1] * len(YX))

    for z in xrange(img.shape[0]):
        YX = np.transpose(np.nonzero(background[z]))
        if DEBUG:
            YX = YX[::10]
        else:
            YX = YX[::2]
        if YX.shape[0] == 0:
            continue
        patches = extract_patches2D(img[z], r, YX)
        patches = np.reshape(
            patches, (patches.shape[0], patches.shape[1] * patches.shape[2]))
        print patches.shape, YX.shape
        X.extend(patches)
        Y.extend([0] * len(YX))

    return X, Y
Beispiel #2
0
 def get_center(self, proba):
     res = irtk.zeros(proba.get_header())
     tmp = proba.view(np.ndarray).copy()
     tmp[self.hard_thresholding(proba) == 0] = 0
     if tmp.sum() == 0:
         return res
     center = np.array(nd.center_of_mass(tmp), dtype='int')
     res[center[0], center[1], center[2]] = 1
     return res
 def get_center( self, proba ):
     res = irtk.zeros( proba.get_header() )
     tmp = proba.view(np.ndarray).copy()
     tmp[self.hard_thresholding(proba)==0] = 0
     if tmp.sum() == 0:
         return res
     center = np.array( nd.center_of_mass( tmp ), dtype='int' )
     res[center[0],center[1],center[2]] = 1
     return res
Beispiel #4
0
def edt( img, mask ):
    if mask.sum() == 0:
        return irtk.zeros(img.get_header())
    voxelSpacing = img.header['pixelSize'][:3][::-1]
    distanceMap = nd.distance_transform_edt( logical_not(mask),
                                             sampling=voxelSpacing)
    distanceMap -= nd.distance_transform_edt( mask,
                                              sampling=voxelSpacing)
    return irtk.Image(distanceMap,img.get_header())
def create_mask_from_all_masks(f_lists,transformations,ga,resolution=0.75):
    points = []
    for f, t in zip(f_lists,transformations):
        m = irtk.imread(f,force_neurological=True)
        points.extend( t.apply(get_corners(m)) )

    points = np.array(points,dtype='float64')
    
    x_min, y_min, z_min = points.min(axis=0)
    x_max, y_max, z_max = points.max(axis=0)

    pixelSize = [resolution, resolution, resolution, 1]
    orientation = np.eye( 3, dtype='float64' )
    origin = [ x_min + (x_max - x_min)/2,
               y_min + (y_max - y_min)/2,
               z_min + (z_max - z_min)/2,
               0 ]
    dim = [ (x_max - x_min)/resolution,
            (y_max - y_min)/resolution,
            (z_max - z_min)/resolution,
            1 ]

    header = irtk.new_header( pixelSize=pixelSize,
                orientation=orientation,
                origin=origin,
                dim=dim )

    mask = irtk.zeros( header, dtype='float32' )

    for f, t in zip( f_lists, transformations ):
        m = irtk.imread(f,force_neurological=True).transform(t, target=mask,interpolation="linear")
        mask += m

    irtk.imwrite( "debug_mask1.nii.gz", mask)
    
    mask = irtk.Image( nd.gaussian_filter( mask, 0.5 ),
                       mask.get_header() )

    irtk.imwrite( "debug_mask2.nii.gz", mask)

    mask = (mask > 0).bbox(crop=True).astype('uint8')

    scale = get_CRL(ga)/get_CRL(30.0)
    template = irtk.imread(f_template,force_neurological=True)
    template.header['pixelSize'][:3] /= scale
    
    template = template.transform(target=mask,interpolation='nearest')
    mask[template==0] = 0

    irtk.imwrite( "debug_template.nii.gz", template)
    irtk.imwrite( "debug_mask3.nii.gz", mask)

    return mask
def mean_shift_selection( votes,
                          n_points=5000,
                          bandwidth=10,
                          n=10,
                          cutoff=None,
                          debug=False,
                          debug_output="./" ):
    points = np.argwhere(votes)
    probas = votes[points[:,0],
                   points[:,1],
                   points[:,2]]
    points, probas = random_pick(points,probas,n_points)

    ms = MeanShift(bandwidth=bandwidth)
    ms.fit(points)

    weights = np.zeros( ms.cluster_centers_.shape[0], dtype='float' )
    for i,c in enumerate(ms.cluster_centers_):
        weights[i] = np.sum(probas[ms.labels_==i])

    detection = ms.cluster_centers_[np.argsort(weights)[::-1]]
    #points = points[np.argsort(weights)[::-1]]
    #ms.labels_ = ms.labels_[np.argsort(weights)[::-1]]
    weights = np.sort(weights)[::-1]

    weights /= weights.max()

    if debug:
        print weights.tolist()
        res = irtk.zeros(votes.get_header(),dtype='int')
        points = np.array(detection,dtype='int')
        if points.shape[0] > 30:
            points = points[:30]
        print np.arange(1,int(points.shape[0]+1))[::-1]
        res[points[:,0],
            points[:,1],
            points[:,2]] = np.arange(1,int(points.shape[0]+1))#[::-1]
        irtk.imwrite(debug_output+"/clusters.nii.gz",res)
        irtk.imwrite(debug_output+"/clusters_centers.nii.gz",irtk.landmarks_to_spheres(res,r=5))
        
    if cutoff is not None:
        selected = np.sum( weights >= cutoff )
        detection = detection[:selected]
        weights = weights[:selected]
    else:
        if len(detection) > n:
            detection = detection[:n]
            weights = weights[:n]

    return detection, weights
Beispiel #7
0
def gdt( img, mask, includeEDT=True, l=1.0 ):
    if mask.sum() == 0:
        return irtk.zeros(img.get_header())
    voxelSpacing = img.header['pixelSize'][:3][::-1]
    grad =  irtk.Image( nd.gaussian_gradient_magnitude(img, 0.5),
                        img.get_header() )
    #irtk.imwrite("gradBefore.nii.gz",grad)
    grad = l*grad.saturate().rescale(0.0,1.0).as3D()
    #irtk.imwrite("gradAfter.nii.gz",grad)
    # distanceMap = geodesic_distance_transform( mask,
    #                                            grad,
    #                                            numIterations=3,
    #                                            spacing=voxelSpacing,
    #                                            includeEDT=includeEDT )
    # distanceMap -= geodesic_distance_transform( logical_not(mask),
    #                                             grad,
    #                                             numIterations=3,
    #                                             spacing=voxelSpacing,
    #                                             includeEDT=includeEDT )
    # return irtk.Image(distanceMap,img.get_header())

    # distanceMaps = Parallel(n_jobs=-1)(delayed(_geodesic_distance_transform)( m,
    #                                                                          grad,
    #                                                                          numIterations=3,
    #                                                                          spacing=voxelSpacing,
    #                                                                          includeEDT=includeEDT )
    #                                                              for m in [mask,
    #                                                                        logical_not(mask)]
    #                                                                          )
    # res = irtk.Image(distanceMaps[0]-distanceMaps[1],img.get_header())

    res = irtk.Image( _geodesic_distance_transform( mask,
                                                    grad,
                                                    numIterations=3,
                                                    spacing=voxelSpacing,
                                                    includeEDT=includeEDT ),
                      img.get_header() ).as3D()

    return res
def get_training_data_regression( img, seg ):
    seg = irtk.imread( seg, dtype='int32', force_neurological=True )
    img = irtk.imread( img, dtype='int32', force_neurological=True )

    #u0,v0,w0 = get_orientation_training(seg)
    brain_center, heart_center, left_lung, right_lung = get_centers(seg)
    
    grad = irtk.Image(nd.gaussian_gradient_magnitude( img, 0.5 ),
                      img.get_header())

    blurred_img = nd.gaussian_filter(img,0.5)
    gradZ = nd.sobel( blurred_img, axis=0 ).astype('float32')
    gradY = nd.sobel( blurred_img, axis=1 ).astype('float32')
    gradX = nd.sobel( blurred_img, axis=2 ).astype('float32')

    new_seg = irtk.zeros( seg.get_header() )
    new_seg[seg==3] = 1 # lung 1
    new_seg[seg==4] = 1 # lung 2
    new_seg[seg==5] = 2 # heart
    new_seg[seg==8] = 3 # liver
    seg = new_seg

    center1 =  np.array(nd.center_of_mass( (seg == 1).view(np.ndarray) ),
                        dtype='float32')
    center2 =  np.array(nd.center_of_mass( (seg == 2).view(np.ndarray) ),
                        dtype='float32')
    center3 =  np.array(nd.center_of_mass( (seg == 3).view(np.ndarray) ),
                        dtype='float32')
    
    sat = integral_image(img)
    sat_grad = integral_image(grad)

    m = np.zeros(img.shape, dtype='uint8')
    m[brain_center[0],
      brain_center[1],
      brain_center[2]] = 1
    
    X = []
    Y = []
    for l in range(1,nb_labels):
        coords = np.argwhere(seg==l)

        coords = coords[np.random.randint( 0,
                                           coords.shape[0],
                                           args.n_samples)].astype('int32')

        if args.not_centered:
            x1 = get_block_comparisons_cpp( sat, coords,
                                            offsets1, sizes1,
                                            offsets2, sizes2,n_jobs=args.n_jobs )
            x2 = get_block_comparisons_cpp( sat_grad, coords,
                                            offsets3, sizes3,
                                            offsets4, sizes4,
                                            n_jobs=args.n_jobs )
            x_grad1 = get_grad( coords.astype('int32'), offsets5.astype('int32'),
                                gradZ.astype('float32'), gradY.astype('float32'), gradX.astype('float32') )
            x_grad2 = get_grad( coords.astype('int32'), offsets6.astype('int32'),
                                gradZ.astype('float32'), gradY.astype('float32'), gradX.astype('float32') )
        else:
            # u = np.tile(u0,(coords.shape[0],1))
            # v = np.tile(v0,(coords.shape[0],1))
            # w = np.tile(w0,(coords.shape[0],1))
            u,v,w = get_orientation_training_jitter( brain_center,
                                                     heart_center,
                                                     left_lung,
                                                     right_lung,
                                                     coords.shape[0],
                                                     brain_jitter=args.brain_jitter,
                                                     heart_jitter=args.heart_jitter,
                                                     lung_jitter=args.lung_jitter )

            x1 = get_block_comparisons_cpp_uvw( sat, coords,
                                                w,v,u,
                                                offsets1, sizes1,
                                                offsets2, sizes2,n_jobs=args.n_jobs )
            x2 = get_block_comparisons_cpp_uvw( sat_grad, coords,
                                                w,v,u,
                                                offsets3, sizes3,
                                                offsets4, sizes4,
                                                n_jobs=args.n_jobs )
            x3 = get_grad_comparisons_cpp_uvw( gradZ, gradY, gradX,
                                               coords,
                                               offsets5, offsets6,
                                               w,v,u,
                                               n_jobs=args.n_jobs )
            # x_grad1 = get_grad_uvw( coords.astype('int32'), offsets5.astype('int32'),
            #                         gradZ.astype('float32'), gradY.astype('float32'), gradX.astype('float32'),
            #                         w.astype('float32'), v.astype('float32'), u.astype('float32') )

            # x_grad2 = get_grad_uvw( coords.astype('int32'), offsets6.astype('int32'),
            #                         gradZ.astype('float32'), gradY.astype('float32'), gradX.astype('float32'),
            #                         w.astype('float32'), v.astype('float32'), u.astype('float32') )
             
        #x = np.concatenate( ( x1, x2, x_grad1 > x_grad2 ), axis=1 )
        x = np.concatenate( ( x1, x2, x3 ), axis=1 )

        if l == 1:
            y = center1[np.newaxis,...] - coords.astype('float32')
            if not args.not_centered:
                y = np.concatenate( ( (y*w).sum(axis=1)[...,np.newaxis],
                                      (y*v).sum(axis=1)[...,np.newaxis],
                                      (y*u).sum(axis=1)[...,np.newaxis] ),
                                    axis=1 )
        elif l == 2:
            y = center2[np.newaxis,...] - coords.astype('float32')
            if not args.not_centered:
                y = np.concatenate( ( (y*w).sum(axis=1)[...,np.newaxis],
                                      (y*v).sum(axis=1)[...,np.newaxis],
                                      (y*u).sum(axis=1)[...,np.newaxis] ),
                                    axis=1 )
        else:
            y = center3[np.newaxis,...] - coords.astype('float32')
            if not args.not_centered:
                y = np.concatenate( ( (y*w).sum(axis=1)[...,np.newaxis],
                                      (y*v).sum(axis=1)[...,np.newaxis],
                                      (y*u).sum(axis=1)[...,np.newaxis] ),
                                    axis=1 )

        X.append(x)
        Y.append(y)
            
    return X,Y
#!/usr/bin/python

import irtk
import scipy.ndimage as nd
import numpy as np
from skimage import morphology

left_lung = irtk.imread("left_lung_prior.nii.gz",force_neurological=False)
right_lung = irtk.imread("right_lung_prior.nii.gz",force_neurological=False)
liver = irtk.imread("liver_prior.nii.gz",force_neurological=False)

average = irtk.imread("/vol/medic02/users/kpk09/gitlab/fetus-detector/body-detector/notebooks/tmp/new_average_heart_center.nii.gz",force_neurological=False)

seg = irtk.imread("/vol/medic02/users/kpk09/gitlab/fetus-detector/body-detector/notebooks/tmp/seg_template.nii.gz",force_neurological=False)

res = irtk.zeros(average.get_header(),dtype='int32')

heart_center = np.array(nd.center_of_mass( (seg == 5).view(np.ndarray) ),
                      dtype='float32')
heart = np.argwhere( (seg == 5).view(np.ndarray) ).astype('float32')
r_heart = np.linalg.norm(heart_center-heart,axis=1).mean()

ball = irtk.Image( morphology.ball(r_heart) )
ball.header['origin'] = np.array([0,0,0],dtype='float64')
ball2 = ball.transform(target=liver)
res[ball2>0] = 5

brain_center = np.array(nd.center_of_mass( (seg == 2).view(np.ndarray) ),
                      dtype='float32')
brain = np.argwhere( (seg == 2).view(np.ndarray) ).astype('float32')
r_brain = np.linalg.norm(brain_center-brain,axis=1).mean()
def mask_image( file_img, file_mask, ga, r, neigh, output_dir ):
    img = irtk.imread( file_img, dtype='float32' )

    input_mask = irtk.imread( file_mask )
    
    print "predicting..."
    res = irtk.zeros( img.get_header(), dtype='float32' )
    res2 = irtk.zeros( img.get_header(), dtype='float32' )
    res3 = irtk.zeros( img.get_header(), dtype='float32' )
    res4 = irtk.zeros( img.get_header(), dtype='uint8' )
    mask = irtk.ones( input_mask.get_header(), dtype='uint8' )
    mask[input_mask == 2] = 0
    for z in xrange(img.shape[0]):
        print z
        YX = np.transpose( np.nonzero( mask[z] ) )
        if YX.shape[0] == 0:
            continue # this slice does not intersect the box
        patches = extract_patches2D( img[z], r, YX )
        patches = np.reshape( patches, (patches.shape[0],patches.shape[1]*patches.shape[2]) )

        predictions = neigh.predict_proba(patches)[:,1]
        res[z,YX[:,0],YX[:,1]] = predictions

    x_min, y_min, z_min, x_max, y_max, z_max = mask.bbox()

    proba = res[z_min:z_max+1,
                y_min:y_max+1,
                x_min:x_max+1]

    if args.mass:
        BV = get_BV( args.ga )
        box_volume = (z_max-z_min)*img.header['pixelSize'][2]*(y_max-y_min)*img.header['pixelSize'][1]*(x_max-x_min)*img.header['pixelSize'][0]
        ratio = float(BV) / float(box_volume)
        print "ratio", ratio
        q0,q1 = mquantiles( proba.flatten(), prob=[0.5*(1.0-ratio),
                                                   1.0-0.5*ratio] )
        print "threshold", q0,q1
        #threshold = max(0.5,threshold)
    
        # labels = res[z_min:z_max+1,
        #              y_min:y_max+1,
        #              x_min:x_max+1] > threshold
        
    #res = 1 / (np.exp(-(res-threshold)/(res.max()-res.min())))

        res[res<q0] = q0
        res[res>q1] = q1
        res -= res.min()
        res /= res.max()

    labels = res[z_min:z_max+1,
                 y_min:y_max+1,
                 x_min:x_max+1] > 0.5
   
    proba = res[z_min:z_max+1,
                y_min:y_max+1,
                x_min:x_max+1]
    
    cropped_img = img[z_min:z_max+1,
                      y_min:y_max+1,
                      x_min:x_max+1]

    if args.do_3D:
        labels = irtk.crf( cropped_img,
                           labels,
                           proba,
                           l=args.l,
                           sigma=get_noiseXY(cropped_img),
                           sigmaZ=get_noiseZ(cropped_img) )
    # elif args.do_patchZ:
    #     labels = irtk.crf_patchZ( cropped_img,
    #                               labels,
    #                               proba,
    #                               l=10.0 )   
    # else:
    #     for z in xrange(z_min,z_max+1):
    #         labels[z] = irtk.crf( cropped_img[z],
    #                               labels[z],
    #                               proba[z],
    #                               l=1.0 )

    print "MAX LABEL:", labels.max()
    irtk.imwrite(output_dir + "/bare_"+os.path.basename(file_img), labels )
    tmp = irtk.zeros( img.get_header(), dtype='uint8' )
    tmp[z_min:z_max+1,
        y_min:y_max+1,
        x_min:x_max+1] = labels
    ( min_x_bare, min_y_bare, min_z_bare,
      max_x_bare, max_y_bare, max_z_bare ) = tmp.bbox()
    
    if not args.no_cleaning:
        # clean by fitting ellipses enlarged of 10%
        for z in xrange(labels.shape[0]):
            edges = nd.morphological_gradient( labels[z] > 0,size=5 )
            points = np.transpose(edges.nonzero())[:,::-1]
            if len(points) == 0:
                continue
            points = np.array(map(lambda x:[x],points),dtype='int32')
            ellipse = cv2.fitEllipse(points)
            cv2.ellipse( labels[z], (ellipse[0],
                                     (1.1*ellipse[1][0],1.1*ellipse[1][1]),
                                     ellipse[2]) , 1, -1 )

    irtk.imwrite(output_dir + "/seg_"+os.path.basename(file_img), labels )
    irtk.imwrite(output_dir + "/res_"+os.path.basename(file_img), res )

    # re-read the image in case we processed it
    img = irtk.imread( file_img, dtype='float32' )
    cropped_img = img[z_min:z_max+1,
                      y_min:y_max+1,
                      x_min:x_max+1]
    cropped_img[labels==0] = -1
    masked = cropped_img.bbox(crop=True)
    irtk.imwrite(output_dir + "/masked_"+os.path.basename(file_img), masked )

    # re-read the image in case we processed it
    img = irtk.imread( file_img, dtype='float32' )    
    x0 = min_x_bare + (max_x_bare - min_x_bare) / 2
    y0 = min_y_bare + (max_y_bare - min_y_bare) / 2
    ofd = get_OFD(ga)/img.header['pixelSize'][0]

    cropped_img = img[min_z_bare:max_z_bare+1,
                      max(0,int(round(y0-ofd/2))):min(img.shape[1],int(round(y0+ofd/2+1))),
                      max(0,int(round(x0-ofd/2))):min(img.shape[2],int(round(x0+ofd/2+1)))].copy()

    irtk.imwrite(output_dir + "/very_large_"+os.path.basename(file_img),
                 cropped_img )
    
    cropped_proba = res[min_z_bare:max_z_bare+1,
                        max(0,int(round(y0-ofd/2))):min(img.shape[1],int(round(y0+ofd/2+1))),
                        max(0,int(round(x0-ofd/2))):min(img.shape[2],int(round(x0+ofd/2+1)))].copy()

    irtk.imwrite(output_dir + "/proba_"+os.path.basename(file_img),
                 cropped_proba )    
def get_training_data( file_img, file_mask, r ):
    # create mask
    input_mask = irtk.imread( file_mask )
    x_min, y_min, z_min, x_max, y_max, z_max = (input_mask == 0).bbox()

    background = irtk.zeros( input_mask.get_header(), dtype='uint8' )
    background[z_min:z_max+1,
               y_min:y_max+1,
               x_min:x_max+1] = 1
    background = nd.morphological_gradient( background, size=7)
    n = background[z_min+1:z_max,
                   y_min+1:y_max,
                   x_min+1:x_max].sum()
    z = np.random.randint(low=0, high=input_mask.shape[0],size=1.25*n)
    y = np.random.randint(low=0, high=input_mask.shape[1],size=1.25*n)
    x = np.random.randint(low=0, high=input_mask.shape[2],size=1.25*n)
    background[z,y,x] = 1
    background[z_min+1:z_max,
               y_min+1:y_max,
               x_min+1:x_max] = 0
    
    foreground = (input_mask == 1).astype('uint8')

    new_mask = irtk.zeros( input_mask.get_header(), dtype='uint8' )
    new_mask[foreground == 1] = 1
    new_mask[background != 0] = 2

    img = irtk.imread( file_img, dtype='float32' )
    
    X = []
    Y = []

    for z in xrange(img.shape[0]):
        YX = np.transpose( np.nonzero( foreground[z] ) )
        if DEBUG:
            YX = YX[::10]
        else:
            YX = YX[::2]
        if YX.shape[0] == 0:
            continue
        patches = extract_patches2D( img[z], r, YX )
        patches = np.reshape( patches, (patches.shape[0],patches.shape[1]*patches.shape[2]) )
        print patches.shape, YX.shape
        X.extend( patches )
        Y.extend( [1]*len(YX) )

    for z in xrange(img.shape[0]):
        YX = np.transpose( np.nonzero( background[z] ) )
        if DEBUG:
            YX = YX[::10]
        else:
            YX = YX[::2]
        if YX.shape[0] == 0:
            continue
        patches = extract_patches2D( img[z], r, YX )
        patches = np.reshape( patches, (patches.shape[0],patches.shape[1]*patches.shape[2]) )
        print patches.shape, YX.shape
        X.extend( patches )
        Y.extend( [0]*len(YX) )

    return X, Y
Beispiel #12
0
def mask_image(file_img, file_mask, ga, r, neigh, output_dir):
    img = irtk.imread(file_img, dtype='float32')

    input_mask = irtk.imread(file_mask)

    print "predicting..."
    res = irtk.zeros(img.get_header(), dtype='float32')
    res2 = irtk.zeros(img.get_header(), dtype='float32')
    res3 = irtk.zeros(img.get_header(), dtype='float32')
    res4 = irtk.zeros(img.get_header(), dtype='uint8')
    mask = irtk.ones(input_mask.get_header(), dtype='uint8')
    mask[input_mask == 2] = 0
    for z in xrange(img.shape[0]):
        print z
        YX = np.transpose(np.nonzero(mask[z]))
        if YX.shape[0] == 0:
            continue  # this slice does not intersect the box
        patches = extract_patches2D(img[z], r, YX)
        patches = np.reshape(
            patches, (patches.shape[0], patches.shape[1] * patches.shape[2]))

        predictions = neigh.predict_proba(patches)[:, 1]
        res[z, YX[:, 0], YX[:, 1]] = predictions

    x_min, y_min, z_min, x_max, y_max, z_max = mask.bbox()

    proba = res[z_min:z_max + 1, y_min:y_max + 1, x_min:x_max + 1]

    if args.mass:
        BV = get_BV(args.ga)
        box_volume = (z_max - z_min) * img.header['pixelSize'][2] * (
            y_max - y_min) * img.header['pixelSize'][1] * (
                x_max - x_min) * img.header['pixelSize'][0]
        ratio = float(BV) / float(box_volume)
        print "ratio", ratio
        q0, q1 = mquantiles(proba.flatten(),
                            prob=[0.5 * (1.0 - ratio), 1.0 - 0.5 * ratio])
        print "threshold", q0, q1
        #threshold = max(0.5,threshold)

        # labels = res[z_min:z_max+1,
        #              y_min:y_max+1,
        #              x_min:x_max+1] > threshold

        #res = 1 / (np.exp(-(res-threshold)/(res.max()-res.min())))

        res[res < q0] = q0
        res[res > q1] = q1
        res -= res.min()
        res /= res.max()

    labels = res[z_min:z_max + 1, y_min:y_max + 1, x_min:x_max + 1] > 0.5

    proba = res[z_min:z_max + 1, y_min:y_max + 1, x_min:x_max + 1]

    cropped_img = img[z_min:z_max + 1, y_min:y_max + 1, x_min:x_max + 1]

    if args.do_3D:
        labels = irtk.crf(cropped_img,
                          labels,
                          proba,
                          l=args.l,
                          sigma=get_noiseXY(cropped_img),
                          sigmaZ=get_noiseZ(cropped_img))
    # elif args.do_patchZ:
    #     labels = irtk.crf_patchZ( cropped_img,
    #                               labels,
    #                               proba,
    #                               l=10.0 )
    # else:
    #     for z in xrange(z_min,z_max+1):
    #         labels[z] = irtk.crf( cropped_img[z],
    #                               labels[z],
    #                               proba[z],
    #                               l=1.0 )

    print "MAX LABEL:", labels.max()
    irtk.imwrite(output_dir + "/bare_" + os.path.basename(file_img), labels)
    tmp = irtk.zeros(img.get_header(), dtype='uint8')
    tmp[z_min:z_max + 1, y_min:y_max + 1, x_min:x_max + 1] = labels
    (min_x_bare, min_y_bare, min_z_bare, max_x_bare, max_y_bare,
     max_z_bare) = tmp.bbox()

    if not args.no_cleaning:
        # clean by fitting ellipses enlarged of 10%
        for z in xrange(labels.shape[0]):
            edges = nd.morphological_gradient(labels[z] > 0, size=5)
            points = np.transpose(edges.nonzero())[:, ::-1]
            if len(points) == 0:
                continue
            points = np.array(map(lambda x: [x], points), dtype='int32')
            ellipse = cv2.fitEllipse(points)
            cv2.ellipse(
                labels[z],
                (ellipse[0],
                 (1.1 * ellipse[1][0], 1.1 * ellipse[1][1]), ellipse[2]), 1,
                -1)

    irtk.imwrite(output_dir + "/seg_" + os.path.basename(file_img), labels)
    irtk.imwrite(output_dir + "/res_" + os.path.basename(file_img), res)

    # re-read the image in case we processed it
    img = irtk.imread(file_img, dtype='float32')
    cropped_img = img[z_min:z_max + 1, y_min:y_max + 1, x_min:x_max + 1]
    cropped_img[labels == 0] = -1
    masked = cropped_img.bbox(crop=True)
    irtk.imwrite(output_dir + "/masked_" + os.path.basename(file_img), masked)

    # re-read the image in case we processed it
    img = irtk.imread(file_img, dtype='float32')
    x0 = min_x_bare + (max_x_bare - min_x_bare) / 2
    y0 = min_y_bare + (max_y_bare - min_y_bare) / 2
    ofd = get_OFD(ga) / img.header['pixelSize'][0]

    cropped_img = img[min_z_bare:max_z_bare + 1,
                      max(0, int(round(y0 - ofd / 2))
                          ):min(img.shape[1], int(round(y0 + ofd / 2 + 1))),
                      max(0, int(round(x0 - ofd / 2))
                          ):min(img.shape[2], int(round(x0 + ofd / 2 +
                                                        1)))].copy()

    irtk.imwrite(output_dir + "/very_large_" + os.path.basename(file_img),
                 cropped_img)

    cropped_proba = res[min_z_bare:max_z_bare + 1,
                        max(0, int(round(y0 - ofd / 2))
                            ):min(img.shape[1], int(round(y0 + ofd / 2 + 1))),
                        max(0, int(round(x0 - ofd / 2))
                            ):min(img.shape[2], int(round(x0 + ofd / 2 +
                                                          1)))].copy()

    irtk.imwrite(output_dir + "/proba_" + os.path.basename(file_img),
                 cropped_proba)
Beispiel #13
0
        region[:,1] *= NEW_SAMPLING
        region[:,2] *= img.header['pixelSize'][2]
        detections.append((center, region))

    return detections

detections = convert_input(image_regions)
print detections
(center, u, ofd), inliers = ransac_ellipses( detections,
                                             ga,
                                             nb_iterations=1000,
                                             model="box",
                                             return_indices=True )

print "initial mask"
mask = irtk.zeros(img.resample2D(NEW_SAMPLING, interpolation='nearest').get_header(),
                  dtype='uint8')

for i in inliers:
    (x,y,z), c = image_regions[i]
    mask[z,c[:,1],c[:,0]] = 1

mask = mask.resample2D(img.header['pixelSize'][0], interpolation='nearest' )

# ellipse mask
ellipse_mask = irtk.zeros(img.resample2D(NEW_SAMPLING, interpolation='nearest').get_header(), dtype='uint8')

for i in inliers:
    (x,y,z), c = image_regions[i]
    ellipse = cv2.fitEllipse(np.reshape(c, (c.shape[0],1,2) ).astype('int32'))
    tmp_img = np.zeros( (ellipse_mask.shape[1],ellipse_mask.shape[2]), dtype='uint8' )
    cv2.ellipse( tmp_img, (ellipse[0],
Beispiel #14
0
start = time()

detector = heartdetector.HeartDetector(name=args.forest)
detector.load()

if not args.time:
    print detector

if not os.path.exists("predictions/" + args.patient_id):
    os.makedirs("predictions/" + args.patient_id)

all_frames = sorted(glob("denoised/" + args.patient_id + "_frame*.nii.gz"))

tmp = irtk.imread(all_frames[0])
mask = irtk.zeros(tmp.get_header(), dtype='float32')
for f in all_frames:
    if "_seg" in f:
        continue
    mask += irtk.imread(f)

mask = (mask > 0).astype('uint8')

# if args.frame is not None:
#     all_frames = [all_frames[args.frame]]
# elif not args.all:
#     ED,ES = get_ED_ES(args.patient_id)
#     all_frames = [all_frames[ED],all_frames[ES]]

for f in all_frames:
    if "_seg" in f:
    
start = time()
    
detector = heartdetector.HeartDetector( name=args.forest )
detector.load()

if not args.time:
    print detector

if not os.path.exists("predictions/"+args.patient_id):
    os.makedirs("predictions/"+args.patient_id)

all_frames = sorted(glob("denoised/"+args.patient_id+"_frame*.nii.gz"))

tmp = irtk.imread(all_frames[0])
mask = irtk.zeros(tmp.get_header(),dtype='float32')
for f in all_frames:
    if "_seg" in f:
        continue
    mask += irtk.imread(f)

mask = (mask > 0).astype('uint8')

# if args.frame is not None:
#     all_frames = [all_frames[args.frame]]
# elif not args.all:
#     ED,ES = get_ED_ES(args.patient_id)
#     all_frames = [all_frames[ED],all_frames[ES]]
    
for f in all_frames:
    if "_seg" in f:
Beispiel #16
0
def get_training_data_classification( img, seg, label_name ):
    seg = irtk.imread( seg, dtype='int32', force_neurological=True )
    img = irtk.imread( img, dtype='int32', force_neurological=True )

    #u0,v0,w0 = get_orientation_training(seg)
    brain_center, heart_center, left_lung, right_lung = get_centers(seg)
    
    grad = irtk.Image(nd.gaussian_gradient_magnitude( img, 0.5 ),
                      img.get_header())

    blurred_img = nd.gaussian_filter(img,0.5)
    gradZ = nd.sobel( blurred_img, axis=0 ).astype('float32')
    gradY = nd.sobel( blurred_img, axis=1 ).astype('float32')
    gradX = nd.sobel( blurred_img, axis=2 ).astype('float32')

    new_seg = irtk.zeros( seg.get_header() )
    if label_name == "lungs":
        new_seg[seg==3] = 1 # lung 1
        new_seg[seg==4] = 1 # lung 2
    elif label_name == "heart":
        new_seg[seg==5] = 1 # heart
    elif label_name == "liver":
        new_seg[seg==8] = 1 # liver
    seg = new_seg

    sat = integral_image(img)
    sat_grad = integral_image(grad)

    m = np.zeros(img.shape, dtype='uint8')
    m[brain_center[0],
      brain_center[1],
      brain_center[2]] = 1

    narrow_band = nd.distance_transform_edt(np.logical_not(m))
    if args.narrow_band:
        narrow_band[narrow_band<30] = 0
        narrow_band[narrow_band>120] = 0
    narrow_band[img==0] = 0
    
    X = []
    Y = []
    for l in range(2):
        coords = np.argwhere(np.logical_and(narrow_band>0,seg==l))

        if l==0:
            coords = coords[np.random.randint( 0,
                                               coords.shape[0],
                                               int(args.factor_background*args.n_samples))].astype('int32')
        else:
            coords = coords[np.random.randint( 0,
                                               coords.shape[0],
                                               args.n_samples)].astype('int32')

        if args.not_centered:
            x1 = get_block_comparisons_cpp( sat, coords,
                                            offsets1, sizes1,
                                            offsets2, sizes2,
                                            n_jobs=args.n_jobs )
            x2 = get_block_comparisons_cpp( sat_grad, coords,
                                            offsets3, sizes3,
                                            offsets4, sizes4,
                                            n_jobs=args.n_jobs )
            x_grad1 = get_grad( coords.astype('int32'), offsets5.astype('int32'),
                                gradZ.astype('float32'), gradY.astype('float32'), gradX.astype('float32'))
            x_grad2 = get_grad( coords.astype('int32'), offsets6.astype('int32'),
                                gradZ.astype('float32'), gradY.astype('float32'), gradX.astype('float32'))
        else:

            if l == 0:
                u,v,w = get_random_orientation(coords.shape[0])
            else:
                # u = np.tile(u0,(coords.shape[0],1))
                # v = np.tile(v0,(coords.shape[0],1))
                # w = np.tile(w0,(coords.shape[0],1))
                u,v,w = get_orientation_training_jitter( brain_center,
                                                         heart_center,
                                                         left_lung,
                                                         right_lung,
                                                         coords.shape[0],
                                                         brain_jitter=args.brain_jitter,
                                                         heart_jitter=args.heart_jitter,
                                                         lung_jitter=args.lung_jitter )

            x1 = get_block_comparisons_cpp_uvw( sat, coords,
                                                w,v,u,
                                                offsets1, sizes1,
                                                offsets2, sizes2,
                                                n_jobs=args.n_jobs )
            x2 = get_block_comparisons_cpp_uvw( sat_grad, coords,
                                                 w,v,u,
                                                offsets3, sizes3,
                                                offsets4, sizes4,
                                                n_jobs=args.n_jobs )
            x3 = get_grad_comparisons_cpp_uvw( gradZ, gradY, gradX,
                                               coords,
                                               offsets5, offsets6,
                                               w,v,u,
                                               n_jobs=args.n_jobs )
            # x_grad1 = get_grad_uvw( coords.astype('int32'), offsets5.astype('int32'),
            #                         gradZ.astype('float32'), gradY.astype('float32'), gradX.astype('float32'),
            #                         w.astype('float32'), v.astype('float32'), u.astype('float32') )

            # x_grad2 = get_grad_uvw( coords.astype('int32'), offsets6.astype('int32'),
            #                         gradZ.astype('float32'), gradY.astype('float32'), gradX.astype('float32'),
            #                         w.astype('float32'), v.astype('float32'), u.astype('float32') )

        R = np.linalg.norm( coords - brain_center, axis=1 )
        #x = np.concatenate( ( x1, x2, x_grad1 > x_grad2, R[...,np.newaxis] ), axis=1 )
        x = np.concatenate( ( x1, x2, x3, R[...,np.newaxis] ), axis=1 )
        
        y = seg[coords[:,0],
                coords[:,1],
                coords[:,2]]

        X.extend(x)
        Y.extend(y)

    return (X,Y)
    img_downsampled = img.resample(img.header['pixelSize']*args.fast)
    #coords2 = np.argwhere(img_downsampled>0).astype('int32')
    coords2 = np.argwhere(narrow_band_downsampled>0).astype('int32')
    coords = img.WorldToImage(img_downsampled.ImageToWorld(coords2[:,::-1]))[:,::-1].astype('int32')
    header = img_downsampled.get_header()
else:
    #coords = np.argwhere(img>0).astype('int32')
    coords = np.argwhere(narrow_band>0).astype('int32')
    header = img.get_header()

if args.chunk_size > len(coords)/2:
    args.chunk_size = len(coords)/2
    print "chunk size too large, setting it to", args.chunk_size

header['dim'][3] = nb_labels
proba = irtk.zeros(header,dtype='float32')

u,v0,w0 = get_orientation(args.brain_center,coords,args.brain_jitter)

# If the location of the brain is unknown,
# we can try random orientations
if args.random:
    u,v0,w0 =  get_random_orientation(coords.shape[0])

best_proba = irtk.zeros(header,dtype='float32')
min_proba = irtk.zeros(header,dtype='float32')
if args.fast:
    best_proba[ 0,
                coords2[:,0],
                coords2[:,1],
                coords2[:,2]] = np.finfo('float32').max
def run( o_size, d_size):
    offsets1 = np.random.randint( -o_size, o_size+1, size=(n_tests,3) ).astype('int32')
    sizes1 = np.random.randint( 0, d_size+1, size=(n_tests,1) ).astype('int32')             
    offsets2 = np.random.randint( -o_size, o_size+1, size=(n_tests,3) ).astype('int32')
    sizes2 = np.random.randint( 0, d_size+1, size=(n_tests,1) ).astype('int32')
    offsets3 = np.random.randint( -o_size, o_size+1, size=(n_tests,3) ).astype('int32')
    sizes3 = np.random.randint( 0, d_size+1, size=(n_tests,1) ).astype('int32')             
    offsets4 = np.random.randint( -o_size, o_size+1, size=(n_tests,3) ).astype('int32')
    sizes4 = np.random.randint( 0, d_size+1, size=(n_tests,1) ).astype('int32') 
    offsets5 = np.random.randint( -o_size, o_size+1, size=(n_tests/3,3) ).astype('int32')
    offsets6 = np.random.randint( -o_size, o_size+1, size=(n_tests/3,3) ).astype('int32')

    # we use only squares for rotation invariance
    sizes1 = np.tile(sizes1,(1,3))
    sizes2 = np.tile(sizes2,(1,3))
    sizes3 = np.tile(sizes3,(1,3))
    sizes4 = np.tile(sizes4,(1,3))
    
    X_train = []
    Y_train = []
    X_test = []
    Y_test = []

    n = 0
    for f in all_files:
        n += 1
        patient_id = os.path.basename(f)[:-len("_img.nii.gz")]
        img = irtk.imread( f, dtype='int32', force_neurological=True )
        seg = irtk.imread( myfolder + "/" + patient_id + "_seg.nii.gz", dtype='int32', force_neurological=True )

        brain_center, heart_center, left_lung, right_lung = get_centers(seg)
    
        grad = irtk.Image(nd.gaussian_gradient_magnitude( img, 0.5 ),
                          img.get_header())

        blurred_img = nd.gaussian_filter(img,0.5)
        gradZ = nd.sobel( blurred_img, axis=0 )
        gradY = nd.sobel( blurred_img, axis=1 )
        gradX = nd.sobel( blurred_img, axis=2 )

        new_seg = irtk.zeros( seg.get_header() )
        new_seg[seg==5] = 1 # heart
        seg = new_seg

        sat = integral_image(img)
        sat_grad = integral_image(grad)

        m = np.zeros(img.shape, dtype='uint8')
        m[brain_center[0],
          brain_center[1],
          brain_center[2]] = 1

        narrow_band = nd.distance_transform_edt(np.logical_not(m))
        narrow_band[narrow_band<30] = 0
        narrow_band[narrow_band>120] = 0
        narrow_band[img==0] = 0
    
        X = []
        Y = []
        for l in range(2):
            coords = np.argwhere(np.logical_and(narrow_band>0,seg==l))

            if l==0:
                coords = coords[np.random.randint( 0,
                                                   coords.shape[0],
                                                   n_samples)].astype('int32')
            else:
                coords = coords[np.random.randint( 0,
                                                   coords.shape[0],
                                                   n_samples)].astype('int32')

            if l == 0:
                u,v,w = get_random_orientation(coords.shape[0])
            else:
                u,v,w = get_orientation_training_jitter( brain_center,
                                                         heart_center,
                                                         left_lung,
                                                         right_lung,
                                                         coords.shape[0],
                                                         brain_jitter=10,
                                                         heart_jitter=5,
                                                         lung_jitter=5 )

            x1 = get_block_comparisons_cpp_uvw( sat, coords,
                                                w,v,u,
                                                offsets1, sizes1,
                                                offsets2, sizes2,
                                                n_jobs=10 )
            x2 = get_block_comparisons_cpp_uvw( sat_grad, coords,
                                                 w,v,u,
                                                offsets3, sizes3,
                                                offsets4, sizes4,
                                                n_jobs=10 )
            x_grad1 = get_grad_uvw( coords.astype('int32'), offsets5.astype('int32'),
                                    gradZ.astype('float32'), gradY.astype('float32'), gradX.astype('float32'),
                                    w.astype('float32'), v.astype('float32'), u.astype('float32') )

            x_grad2 = get_grad_uvw( coords.astype('int32'), offsets6.astype('int32'),
                                    gradZ.astype('float32'), gradY.astype('float32'), gradX.astype('float32'),
                                    w.astype('float32'), v.astype('float32'), u.astype('float32') )

            x = np.concatenate( ( x1, x2, x_grad1 > x_grad2 ), axis=1 )
            #x = np.concatenate( ( x1, x2 ), axis=1 )
        
            y = seg[coords[:,0],
                    coords[:,1],
                    coords[:,2]]
            
            if n < 30:
                X_train.extend(x)
                Y_train.extend(y)
            else:
                X_test.extend(x)
                Y_test.extend(y)

    print "train:",len(X_train),len(Y_train)
    forest = RandomForestClassifier( n_estimators=100,
                                     oob_score=True,
                                     n_jobs=10 )#,min_samples_leaf=10)

    forest.fit(X_train,Y_train)
    oob_score = forest.oob_score_

    print "test:",len(X_test),len(Y_test)
    test_score = forest.score( X_test, Y_test)

    print [oob_score,test_score,o_size,d_size]
    return [oob_score,test_score,o_size,d_size]
                                                  output_folder=output_dir )

print "Fit box with RANSAC"
center, selection = ransac_ellipses( detected_centers,
                                     detected_regions,
                                     img_resampled,
                                     ga,
                                     nb_iterations=1000,
                                     debug=args.debug)

selected_centers = detected_centers[selection]
selected_regions = detected_regions[selection]

print "initial mask"

mask = irtk.zeros(img_resampled.get_header(), dtype='uint8')

# ellipse mask
ellipse_mask = irtk.zeros(img_resampled.get_header(), dtype='uint8')

for c,r in zip(selected_centers,selected_regions):
    mask[c[0],r[:,1],r[:,0]] = 1

    ellipse = cv2.fitEllipse(np.reshape(r, (r.shape[0],1,2) ).astype('int32'))
    tmp_img = np.zeros( (ellipse_mask.shape[1],ellipse_mask.shape[2]), dtype='uint8' )
    cv2.ellipse( tmp_img, (ellipse[0],
                           (ellipse[1][0],ellipse[1][1]),
                           ellipse[2]) , 1, thickness=-1)
    ellipse_mask[c[0]][tmp_img > 0] = 1

mask[ellipse_mask == 1] = 1
Beispiel #20
0
        detections.append((center, region))

    return detections


detections = convert_input(image_regions)
print detections
(center, u, ofd), inliers = ransac_ellipses(detections,
                                            ga,
                                            nb_iterations=1000,
                                            model="box",
                                            return_indices=True)

print "initial mask"
mask = irtk.zeros(img.resample2D(NEW_SAMPLING,
                                 interpolation='nearest').get_header(),
                  dtype='uint8')

for i in inliers:
    (x, y, z), c = image_regions[i]
    mask[z, c[:, 1], c[:, 0]] = 1

mask = mask.resample2D(img.header['pixelSize'][0], interpolation='nearest')

# ellipse mask
ellipse_mask = irtk.zeros(img.resample2D(NEW_SAMPLING,
                                         interpolation='nearest').get_header(),
                          dtype='uint8')

for i in inliers:
    (x, y, z), c = image_regions[i]
import argparse

parser = argparse.ArgumentParser(
    description='' )
parser.add_argument( '--seg', type=str, required=True )
parser.add_argument( '--img', type=str, required=True )
parser.add_argument( '--output', type=str, required=True )
parser.add_argument( '--narrow_band', type=int, default=5 )
parser.add_argument( '--debug', action="store_true", default=False )

args = parser.parse_args()

seg = irtk.imread( args.seg, dtype='int32', force_neurological=True )
img = irtk.imread( args.img, dtype='float32', force_neurological=True ).rescale(0,1000)

res = irtk.zeros( seg.get_header(), dtype='uint8' )

ball = morphology.ball( args.narrow_band )

nb_labels = 5

# for i in range(1,5):
#     tmp_seg = (seg==i).astype('int32')
#     # crop
#     x_min,y_min,z_min,x_max,y_max,z_max = (tmp_seg).bbox()
#     mask = tmp_seg[max(0,z_min-2*args.narrow_band):min(seg.shape[0],z_max+2*args.narrow_band+1),
#                       max(0,y_min-2*args.narrow_band):min(seg.shape[1],y_max+2*args.narrow_band+1),
#                       max(0,x_min-2*args.narrow_band):min(seg.shape[2],x_max+2*args.narrow_band+1)]
#     tmp_img = img[max(0,z_min-2*args.narrow_band):min(img.shape[0],z_max+2*args.narrow_band+1),
#                   max(0,y_min-2*args.narrow_band):min(img.shape[1],y_max+2*args.narrow_band+1),
#                   max(0,x_min-2*args.narrow_band):min(img.shape[2],x_max+2*args.narrow_band+1)]
    #coords2 = np.argwhere(img_downsampled>0).astype('int32')
    coords2 = np.argwhere(narrow_band_downsampled>0).astype('int32')
    coords = img.WorldToImage(img_downsampled.ImageToWorld(coords2[:,::-1]))[:,::-1].astype('int32')
    header = img_downsampled.get_header()
else:
    #coords = np.argwhere(img>0).astype('int32')
    coords = np.argwhere(narrow_band>0).astype('int32')
    header = img.get_header()

if args.chunk_size > len(coords)/2:
    args.chunk_size = len(coords)/2
    if args.verbose:
        print "chunk size too large, setting it to", args.chunk_size
    
header['dim'][3] = nb_labels
proba = irtk.zeros(header,dtype='float32')

if args.aligned:
    u = np.zeros((coords.shape[0],3),dtype='float32')
    u[:,2] = 1 # heart to brain
    v0 = np.zeros((coords.shape[0],3),dtype='float32')
    v0[:,1] = 1 # left to right
    # w0 = np.zeros((coords.shape[0],3),dtype='float32')
    # w0[:,0] = -1 # np.cross(u,v)
    w0 = np.cross(u,v0)
    args.theta = 360
elif args.random:
    # If the location of the brain is unknown,
    # we can try random orientations
    u,v0,w0 =  get_random_orientation(coords.shape[0])
else: