def predict( self,
             filename,
             nb_autocontext=None,
             mask=None,
             debug=False,
             return_all=False ):
    """
    The prediction function must be defined outside of the main class in order to be used in joblib's Parallel.
    """
    nb_labels = len(self.params['labels'])+1
    
    if nb_autocontext is None:
        nb_autocontext = len(glob(self.params['name'] + "_*"))

    if self.params['predict_preprocessing_function'] is None:
        img = irtk.imread( filename, dtype="float32" )
        img = img.resample( pixelSize=self.params['resample'], interpolation='linear' ).rescale(0,1000)
    else:
        img = self.params['predict_preprocessing_function'](self, filename).copy()
    
    if mask is None:
        mask = irtk.ones( img.get_header(), dtype="uint8" ).as3D()
        mask[img==0] = 0
    else:
        mask = mask.resample( pixelSize=self.params['resample'], interpolation='nearest' ).astype('uint8')
    
    probas = predict_autocontext( self,
                                  img,
                                  mask,
                                  nb_labels,
                                  nb_autocontext,
                                  debug=debug,
                                  return_all=return_all )
    
    return probas
def get_center_brain_detection(f,world=True):
    input_mask = irtk.imread( f, force_neurological=False )
    mask = irtk.ones( input_mask.get_header(), dtype='uint8' )
    mask[input_mask == 2] = 0
    x_min, y_min, z_min, x_max, y_max, z_max = map( float, mask.bbox() )
    center = [ x_min + (x_max-x_min)/2,
               y_min + (y_max-y_min)/2,
               z_min + (z_max-z_min)/2 ]
    if not world:
        center = np.array(center,dtype='float64')[::-1]
        return center
    else:
        center = input_mask.ImageToWorld(center)
        return center
Beispiel #3
0
def predict(self,
            filename,
            ga,
            nb_autocontext=None,
            mask=None,
            debug=False,
            return_all=False):
    nb_labels = len(self.labels) + 1

    if nb_autocontext is None:
        nb_autocontext = len(glob(self.params['name'] + "_*"))

    img = irtk.imread(filename, dtype="float32")
    img = img.resample(pixelSize=self.params['resample'],
                       interpolation='linear').rescale(0, 1000)

    extra_layers = []

    if mask is None:
        mask = irtk.ones(img.get_header(), dtype="uint8")
        mask[img == 0] = 0
    else:
        mask = mask.resample(pixelSize=self.params['resample'],
                             interpolation='nearest').astype('uint8')

    metadata = None

    probas = predict_autocontext(self,
                                 img,
                                 mask,
                                 np.array(extra_layers, dtype="float32"),
                                 metadata,
                                 nb_labels,
                                 ga,
                                 nb_autocontext,
                                 debug=debug,
                                 return_all=return_all)

    return probas
def predict( self,
             filename,
             ga,
             nb_autocontext=None,
             mask=None,
             debug=False,
             return_all=False ):
    nb_labels = len(self.labels)+1
    
    if nb_autocontext is None:
        nb_autocontext = len(glob(self.params['name'] + "_*"))

    img = irtk.imread( filename, dtype="float32" )
    img = img.resample( pixelSize=self.params['resample'], interpolation='linear' ).rescale(0,1000)

    extra_layers = []

    if mask is None:
        mask = irtk.ones( img.get_header(), dtype="uint8" )
        mask[img==0] = 0
    else:
        mask = mask.resample( pixelSize=self.params['resample'], interpolation='nearest' ).astype('uint8')

    metadata = None
    
    probas = predict_autocontext( self,
                                  img,
                                  mask,
                                  np.array( extra_layers, dtype="float32" ),
                                  metadata,
                                  nb_labels,
                                  ga,
                                  nb_autocontext,
                                  debug=debug,
                                  return_all=return_all )
    
    return probas
def preprocess_training_data( patient_id,
                              img_folder,
                              seg_folder,
                              resample,
                              offline=False,
                              online=True):
    if offline or online:
        if ( offline
             and os.path.exists( "offline_preprocessing/"+patient_id+"_img.nii.gz" )
             and os.path.exists( "offline_preprocessing/"+patient_id+"_seg.nii.gz" ) ):
                 return
        img = irtk.imread( img_folder + "/" + patient_id + ".nii.gz",
                           dtype='float32' )
        seg = irtk.imread( seg_folder +"/"+patient_id+"_seg.nii.gz",
                           dtype="uint8" )

        wall = nd.binary_dilation( seg,
                                   morphology.ball(int(12.5*0.001/seg.header['pixelSize'][0])) )
        wall = wall.astype('int')
        points = np.transpose(np.nonzero(wall))[::4]
        center,S,V = fit_ellipsoidPCA( points )
        if V[0,0] < 0:
            V *= -1
        
        points = np.transpose(np.nonzero(wall))
        projections = np.dot(points-center,V[0])

        # valves
        index = projections > (projections.max() - 40.0*0.001/seg.header['pixelSize'][0])

        #print "VALVE size:",np.sum(index), projections.max(), 40.0*0.001/seg.header['pixelSize'][0]
    
        wall[points[index,0],
             points[index,1],
             points[index,2]] = 2

        #print "VALVE1", wall.max()

        wall = irtk.Image(wall,seg.get_header())
    
        img = img.resample( pixelSize=resample, interpolation='linear' ).rescale(0,1000)
        seg = seg.transform(target=img,interpolation="nearest").astype('uint8')
        wall = wall.transform(target=img,interpolation="nearest").astype('uint8')
 
        wall[seg>0] = 0
        seg[wall==1] = 2
        seg[wall==2] = 3

        #print "VALVE2", seg.max()
    
        #irtk.imwrite("debug/"+patient_id+"_border.nii.gz",seg)
    
        seg[img==0] = 255

        if offline:
            irtk.imwrite( "offline_preprocessing/"+patient_id+"_img.nii.gz", img )
            irtk.imwrite( "offline_preprocessing/"+patient_id+"_seg.nii.gz", seg )
            return

    if not online:
        img = irtk.imread( "offline_preprocessing/"+patient_id+"_img.nii.gz" )
        seg = irtk.imread( "offline_preprocessing/"+patient_id+"_seg.nii.gz" )
        
    mask = irtk.ones( img.get_header(), dtype='uint8' )
    mask[img==0] = 0

    return { 'patient_id': patient_id,
             'img' : img,
             'seg' : seg,
             'mask' : mask }
irtk.imwrite( args.output + "/proba.nii.gz", proba )

irtk.imwrite( args.output + "/min_proba.nii.gz", min_proba )

seg = np.argmax( proba, axis=0)
seg = irtk.Image( seg,
                  img.get_header() ).astype('uint8')

irtk.imwrite( args.output + "/seg.nii.gz", seg )

# Regression
print "doing regression"
header = img.get_header()
header['dim'][3] = 3
offsets_heart = irtk.ones(header,dtype='float32') * np.finfo('float32').max
for l, forest, offsets in zip( [1],
                               [reg_heart],
                               [offsets_heart] ):  

    if args.theta < 360 and args.selective:
        selection = np.logical_and( proba[l,
                                          coords[:,0],
                                          coords[:,1],
                                          coords[:,2]]>0.5,
                                    min_proba[l,
                                              coords[:,0],
                                              coords[:,1],
                                              coords[:,2]]<0.5 )
    else:
        selection = proba[l,
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 #8
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 #9
0
def preprocess_training_data(patient_id,
                             img_folder,
                             seg_folder,
                             resample,
                             offline=False,
                             online=True):
    if offline or online:
        if (offline and os.path.exists("offline_preprocessing/" + patient_id +
                                       "_img.nii.gz")
                and os.path.exists("offline_preprocessing/" + patient_id +
                                   "_seg.nii.gz")):
            return
        img = irtk.imread(img_folder + "/" + patient_id + ".nii.gz",
                          dtype='float32')
        seg = irtk.imread(seg_folder + "/" + patient_id + "_seg.nii.gz",
                          dtype="uint8")

        wall = nd.binary_dilation(
            seg,
            morphology.ball(int(12.5 * 0.001 / seg.header['pixelSize'][0])))
        wall = wall.astype('int')
        points = np.transpose(np.nonzero(wall))[::4]
        center, S, V = fit_ellipsoidPCA(points)
        if V[0, 0] < 0:
            V *= -1

        points = np.transpose(np.nonzero(wall))
        projections = np.dot(points - center, V[0])

        # valves
        index = projections > (projections.max() -
                               40.0 * 0.001 / seg.header['pixelSize'][0])

        #print "VALVE size:",np.sum(index), projections.max(), 40.0*0.001/seg.header['pixelSize'][0]

        wall[points[index, 0], points[index, 1], points[index, 2]] = 2

        #print "VALVE1", wall.max()

        wall = irtk.Image(wall, seg.get_header())

        img = img.resample(pixelSize=resample,
                           interpolation='linear').rescale(0, 1000)
        seg = seg.transform(target=img,
                            interpolation="nearest").astype('uint8')
        wall = wall.transform(target=img,
                              interpolation="nearest").astype('uint8')

        wall[seg > 0] = 0
        seg[wall == 1] = 2
        seg[wall == 2] = 3

        #print "VALVE2", seg.max()

        #irtk.imwrite("debug/"+patient_id+"_border.nii.gz",seg)

        seg[img == 0] = 255

        if offline:
            irtk.imwrite("offline_preprocessing/" + patient_id + "_img.nii.gz",
                         img)
            irtk.imwrite("offline_preprocessing/" + patient_id + "_seg.nii.gz",
                         seg)
            return

    if not online:
        img = irtk.imread("offline_preprocessing/" + patient_id +
                          "_img.nii.gz")
        seg = irtk.imread("offline_preprocessing/" + patient_id +
                          "_seg.nii.gz")

    mask = irtk.ones(img.get_header(), dtype='uint8')
    mask[img == 0] = 0

    return {
        'patient_id': patient_id,
        'img': img,
        'seg': seg,
        'extra_layers': np.array([], dtype='float32'),
        'metadata': None,
        'mask': mask
    }
    proba = proba.transform(target=header)

if not args.score:
    irtk.imwrite( args.output + "/proba.nii.gz", proba )

seg = np.argmax( proba, axis=0)
seg = irtk.Image( seg,
                  img.get_header() ).astype('uint8')

if not args.score:
    irtk.imwrite( args.output + "/seg.nii.gz", seg )

# Regression
header = img.get_header()
header['dim'][3] = 3
offsets_heart = irtk.ones(header,dtype='float32') * np.finfo('float32').max
offsets_left_lung = irtk.ones(header,dtype='float32') * np.finfo('float32').max
offsets_right_lung = irtk.ones(header,dtype='float32') * np.finfo('float32').max
offsets_liver = irtk.ones(header,dtype='float32') * np.finfo('float32').max
for l, forest, offsets in zip( [1,2,3,4],#range(1,nb_labels),
                               [reg_left_lung,reg_right_lung,reg_heart,reg_liver],
                               [offsets_left_lung,offsets_right_lung,offsets_heart,offsets_liver] ):  

    selection = seg[coords[:,0],
                    coords[:,1],
                    coords[:,2]] == l
    
    coords_reg = coords[selection].astype('int32').copy()
    u2 = u[selection].copy()
    v2 = v[selection].copy()
    w2 = w[selection].copy()