예제 #1
0
파일: tile_data_GSL.py 프로젝트: gliu2/CSim
def test_gettiles3d():
    print('Image:')
    filepath1 = mat.uigetfile()
    this_image = mpimg.imread(filepath1)
    print('Image dims: ' + str(np.ndim(this_image)))
    print('Image shape: ' + str(np.shape(this_image)))

    print('Mask:')
    filepath2 = mat.uigetfile()
    this_mask = mpimg.imread(filepath2)
    print('Mask dims: ' + str(np.ndim(this_mask)))
    print('Mask shape: ' + str(np.shape(this_mask)))

    im2_tiles = gettiles3d(this_image, this_mask)
    #    im2_tiles = gettiles3d(this_image, np.ones(np.shape(this_image))) # no mask

    print('Original image:')
    plt.figure()
    plt.imshow(this_image)
    print('Num tiles: ' + str(len(im2_tiles)))
    for i in range(len(im2_tiles)):
        plt.figure()
        plt.imshow(im2_tiles[i])
예제 #2
0
def main():
#    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    
    #User select an image patch 
    print('Select an unprocessed, multispectral (.pkl) image patch file:')
    path_testpatch = mat.uigetfile(initialdir='C:/Users/CTLab/Documents/George/Python_data/arritissue_data/', title='Select file', filetypes=(("pickle files","*.pkl"),("all files","*.*")))
    print(path_testpatch)
    
    # Load selected image patch
    x_testpatch = pickle_loader(path_testpatch) # ndarray shape (H, W, C)
    # Make image-patch 4-D array prior to classification
    x_testpatch = np.expand_dims(x_testpatch, axis=0) # ndarray shape (N=1, H, W, C)
    x_testpatch = np.transpose(x_testpatch, axes=(0, 3, 1, 2)) # conversion of numpy array (N, H, W, C) to a shape (N, C, H, W) 
    
    # Classify image patch
    y, y_prob, y_pred_ind, y_pred_classnames = classify(x_testpatch)
    print('')
    print('Prediction class scores: ', y)
    print('Prediction class probabilities: ', y_prob)
    print('Sum of probabilities =', np.sum(y_prob, axis=1))
    print('Prediction class indices: ', y_pred_ind)
    print('Prediction class names: ', y_pred_classnames)
    
    print('Done')
def main():
  
    # Get start time for this run
    timestr = time.strftime("%Y%m%d-%H%M%S")
    print(timestr)
    
    # for tt in range(1):
    for tt in range(30):  # include this for loop to randomly sample learning rate, other hyperparameters
        # Get start time for this run
        timestr = time.strftime("%Y%m%d-%H%M%S")
        print(timestr)
    
        xx = 3 + random.random()*1
        LEARNING_RATE = 10**-xx
        
        # random search hyperparameters
        yy = 3 + random.random()*1
        ALPHA_L2REG = 1*10**-yy
        
        zz = random.random()*0
        DROPOUT_RATE = zz
    
        print('Iteration: ', tt, LEARNING_RATE , ALPHA_L2REG, DROPOUT_RATE)
    
        for xx in [True]:
        # for xx in [True, False]:
            ISMULTISPECTRAL = xx
        
            #%% Data loading
            if ISMULTISPECTRAL: # 21-channel pickled tiled images
                # set paths to RGB images
                data_dir = PATH_PATCHES3D
                out_path = PATH_OUTPUT3D
                
                # Data augmentation and normalization for training
                # Just normalization for validation
                data_transforms = {
                    'train': transforms.Compose([
                        transforms.ToTensor(),
                        transforms.Normalize(MEAN_CHANNEL_PIXELVALS, STD_CHANNEL_PIXELVALS)
                    ]),
                    'val': transforms.Compose([
                        transforms.ToTensor(),
                        transforms.Normalize(MEAN_CHANNEL_PIXELVALS, STD_CHANNEL_PIXELVALS)
                    ]),
                    'test': transforms.Compose([
                        transforms.ToTensor(),
                        transforms.Normalize(MEAN_CHANNEL_PIXELVALS, STD_CHANNEL_PIXELVALS)
                    ]),
                }
                
                num_channels = 21 - N_REMOVED
                
            else: # RGB 3-channel, pickled images
                # set paths to RGB images
                data_dir = PATH_PATCHES2D
                out_path = PATH_OUTPUT2D
                        
                # Data augmentation and normalization for training
                # Just normalization for validation
                data_transforms = {
                    'train': transforms.Compose([
                        transforms.ToTensor(),
                        transforms.Normalize(MEAN_CHANNEL_PIXELVALS[:3], STD_CHANNEL_PIXELVALS[:3])
                    ]),
                    'val': transforms.Compose([
                        transforms.ToTensor(),
                        transforms.Normalize(MEAN_CHANNEL_PIXELVALS[:3], STD_CHANNEL_PIXELVALS[:3])
                    ]),
                    'test': transforms.Compose([
                        transforms.ToTensor(),
                        transforms.Normalize(MEAN_CHANNEL_PIXELVALS[:3], STD_CHANNEL_PIXELVALS[:3])
                    ]),
                }
                
                num_channels = 3
    
            image_datasets = {x: datasets.DatasetFolder(os.path.join(data_dir, x), loader=pickle_loader, 
                                                        extensions='.pkl', transform=data_transforms[x])
                             for x in ['train', 'val', 'test']}
                
            print('Num channels', num_channels)
            if not LOADMODEL:
                dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=BATCH_SIZE,
                                                         shuffle=True, num_workers=0)
                              for x in ['train', 'val', 'test']}
            else:
                dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=BATCH_SIZE,
                                                         shuffle=False, num_workers=0)
                              for x in ['train', 'val', 'test']}
            dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val', 'test']}
            class_names = image_datasets['train'].classes
            num_classes = len(class_names)
            
            device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
            print('Dataset sizes', dataset_sizes)
            print('Number of classes', num_classes)
            print('GPU vs CPU:', device)
                    
            #%%Finetuning the convnet
            #Load a pretrained model and reset final fully connected layer.
        #    model_ft = models.resnet18(pretrained=True)
            model_ft = densenet_av.densenet_40_12_bc(pretrained=ISPRETRAINED, in_channels=num_channels, drop_rate=DROPOUT_RATE)
            num_ftrs = model_ft.fc.in_features
            print('model_ft.fc.in_features =', num_ftrs) #debugging
            model_ft.fc = nn.Linear(num_ftrs, num_classes)
            
            model_ft = model_ft.to(device)
            
            criterion = nn.CrossEntropyLoss()
            
            # Observe that all parameters are being optimized
        #    optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9)
            optimizer_ft = optim.Adam(model_ft.parameters(),  lr=LEARNING_RATE, weight_decay=ALPHA_L2REG) # defaulat ADAM lr = 0.001
            
            # Decay LR by a factor of 0.1 every 7 epochs
            exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=LRDECAY_STEP, gamma=LRDECAY_GAMMA)
    #            exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=1000, gamma=LRDECAY_GAMMA) # For Adam optimizer, no need for LR decay
            
            #%% Train and evaluate
            if LOADMODEL: # load weights instead of training
                print('Loading model... Select loss/acc file:')
                filepath = mat.uigetfile()
                [cache_loss, cache_acc] = pickle.load(open(filepath, "rb"))
                print('Loading model... ')
                modelpath = filepath.replace('lossacc', 'modelparam').replace('.pkl', '.pt')
                model_ft.load_state_dict(torch.load(modelpath))
                model_ft.eval()
                
                # Get same filename for saving
                path_head, path_tail = os.path.split(filepath)
                filename_pre, path_ext = os.path.splitext(path_tail)
                
    #            # 8-25-2019
    #            # Obtain per-image classification accuracy based on patches - loop through folders without dataloader
    #            for phase in ['train', 'val', 'test']:
    #                data_dir2 = os.path.join(data_dir, phase)
    #                tissues = os.listdir(data_dir2) # should be num_classes # of folders
    #                print('Evaluating per-specimen accuracy on dataset: ', phase)
    #                
    #                # Iterate over tissue classes
    #                for tt, tissue in enumerate(tissues):
    #                    tissue_folder = os.path.join(data_dir2, tissue)
    #                    tissue_files = os.listdir(tissue_folder)
    #                    tissue_dates = [i.split('_', 1)[0] for i in tissue_files]
    #                    unique_dates = list(set(tissue_dates))
    ##                    print(unique_dates)
    #                    num_dates = np.size(unique_dates)
    #                    
    #                    num_patches_tissue_date = np.zeros((num_dates, 1))
    #                    num_correctpatches_tissue_date = np.zeros((num_dates, 1))
    #                    iscorrect_tissue_date = np.zeros((num_dates, 1))
    #                    
    #                    # Calculate fraction of correct patch predictions per tissue-date specimen
    #                    num_patches = 0
    #                    for i, session in enumerate(unique_dates):
    ##                        print(session)
    #                        num_patches_tissue_date[i] = tissue_dates.count(session)
    #                        tissue_patches_session_filenames = [item for item in tissue_files if item.startswith(session)]
    #                        
    #                        # Load patches into one batch of shape [M, C, H, W]
    #                        # where M is batch size (# patches), C is # channels
    #                        patches_session = np.zeros((int(num_patches_tissue_date[i]), num_channels, TILE_HEIGHT, TILE_WIDTH))
    #                        for j, patch_filename in enumerate(tissue_patches_session_filenames):
    #                            if ISMULTISPECTRAL:
    #                                this_image = pickle_loader(os.path.join(tissue_folder, patch_filename)) # read image, shape (H, W, 21)
    #                                mean = np.array(MEAN_CHANNEL_PIXELVALS) 
    #                                std = np.array(STD_CHANNEL_PIXELVALS)
    #                                inp = (this_image - mean)/std
    #                            else:
    #                                this_image = mpimg.imread(os.path.join(tissue_folder, patch_filename)) # read image, shape (H, W, 3)
    #                                mean = np.array(MEAN_CHANNEL_PIXELVALS[:3]) 
    #                                std = np.array(STD_CHANNEL_PIXELVALS[:3])
    #                                inp = (this_image - mean)/std
    #                                
    ##                            plt.figure(), plt.imshow(this_image[:,:,:3])
    ##                            print(os.path.join(tissue_folder, patch_filename))
    ##                            sys.exit()
    #                            patches_session[j] = inp.transpose((2, 0, 1))
    #                        
    #                        # Predict on patches
    #                        with torch.no_grad():
    #                            inputs = torch.tensor(patches_session, dtype=torch.float).to(device)
    #                            outputs = model_ft(inputs)
    #                            _, preds = torch.max(outputs, 1)
    #                            
    ##                        print(preds)
    #                        
    #                        # Calculate number correct patches
    #                        true_label = tt
    #                        num_correctpatches_tissue_date[i] = np.sum(preds.cpu().numpy()==true_label)
    #                        iscorrect_tissue_date[i] = (num_correctpatches_tissue_date[i]/num_patches_tissue_date[i])>=0.5 # Assume 50% or greater patches predictions gives the overall specimen prediction
    #                        
    ##                        num_patches = num_patches + num_patches_tissue_date[i]
    ##                        print('  correct', num_correctpatches_tissue_date[i], num_patches_tissue_date[i], iscorrect_tissue_date[i])
    ##                    print(num_patches)
    #                    
    #                    # Output per-specimen results
    #                    specimens_correct = np.sum(iscorrect_tissue_date)
    #                    print('  ', tissue, ': correct specimens ', specimens_correct, ' out of ', num_dates)
                
            else: # Train model from scratch
                print('Train model...')
                # Train
                #It should take around 15-25 min on CPU. On GPU though, it takes less than a minute.
                model_ft, cache_loss, cache_acc = train_model(model_ft, criterion, optimizer_ft, exp_lr_scheduler,
                                       dataloaders, device, dataset_sizes, num_epochs=NUM_EPOCHS)
                   
                # Save loss and acc to disk
                filename_pre = 'nclass' + str(num_classes)
                t_size, val_acc = zip(*cache_acc['val']) # Calculate best val acc
                bestval_acc =  max(val_acc).item()
                
    #            filename_pre = timestr + '_nclass' + str(num_classes) + '_pretrain' + str(ISPRETRAINED)+ '_batch' + str(BATCH_SIZE) + '_epoch' + str(NUM_EPOCHS) + '_lr' + str(LEARNING_RATE) + '_' + str(LRDECAY_STEP) + '_' + str(LRDECAY_GAMMA) + '_val' +"{:.4f}".format(bestval_acc)
                filename_pre = timestr + '_multispec' + str(ISMULTISPECTRAL) + '_nclass' + str(num_classes) + '_pretrain' + str(ISPRETRAINED)+ '_batch' + str(BATCH_SIZE) + '_epoch' + str(NUM_EPOCHS) + '_lr' + str(LEARNING_RATE) + '_L2reg' + str(ALPHA_L2REG) + '_DROPOUT' + str(DROPOUT_RATE) + '_val' +"{:.4f}".format(bestval_acc)
                filename = 'lossacc_' + filename_pre + '.pkl'
                pickle.dump([cache_loss, cache_acc], open(os.path.join(out_path, filename), "wb" ))
                
                # Save trained model's parameters for inference
                filename2 = 'modelparam_' + filename_pre + '.pt'
                torch.save(model_ft.state_dict(), os.path.join(out_path, filename2))
            
            # Evaluate 
            model_ft.eval() # set dropout and batch normalization layers to evaluation mode before running inference
            
    #        # Examine each figure and output to get granular prediction output info
    ##        fig0 = visualize_model(model_ft,  dataloaders, device, class_names, num_images=90, columns=10)
    ##        fig0 = visualize_model(model_ft,  dataloaders, device, class_names, num_images=10) # visualize validation images
    #        fig0 = visualize_model(model_ft,  dataloaders, device, class_names, num_images=288, columns=12, phase='test')
    #        # Save visualization figure
    #        fig0_filename = 'visualize_' + filename_pre + '.png'
    #        fig0 = plt.gcf()
    #        fig0.set_size_inches(FIG_HEIGHT, FIG_WIDTH)
    #        plt.savefig(os.path.join(out_path, fig0_filename), bbox_inches='tight', dpi=FIG_DPI)
            
            fig1, fig2 = learning_curve(cache_loss, cache_acc, class_names, num_epochs=NUM_EPOCHS)
            
            # Save learning curve figures
            fig1_filename = 'losscurve_' + filename_pre + '.pdf'
            fig2_filename = 'acccurve_' + filename_pre + '.pdf'
            fig1.set_size_inches(FIG_HEIGHT, FIG_WIDTH)
            fig2.set_size_inches(FIG_HEIGHT, FIG_WIDTH)
            fig1.savefig(os.path.join(out_path, fig1_filename), bbox_inches='tight', dpi=FIG_DPI)
            fig2.savefig(os.path.join(out_path, fig2_filename), bbox_inches='tight', dpi=FIG_DPI)
            
            # Display confusion matrix
            for phase in ['train', 'val', 'test']:
                confusion_matrix = torch.zeros(num_classes, num_classes)
                y_actu = []
                y_pred = []
                with torch.no_grad():
                    for i, (inputs, classes) in enumerate(dataloaders[phase]):
                        inputs = inputs.to(device, dtype=torch.float) # shape [128, 21, 36, 36]
                        classes = classes.to(device)
                        outputs = model_ft(inputs)
                        _, preds = torch.max(outputs, 1)
                        for t, p in zip(classes.view(-1), preds.view(-1)):
                            confusion_matrix[t.long(), p.long()] += 1
                        
                        # Vector of class labels and predictions
                        y_actu = np.hstack((y_actu, classes.view(-1).cpu().numpy()))
                        y_pred = np.hstack((y_pred, preds.view(-1).cpu().numpy()))
            
        #        print(confusion_matrix)
                print(confusion_matrix.diag()/confusion_matrix.sum(1)) # per-class accuracy
                fig3 = plot_confusion_matrix(confusion_matrix, classes=class_names, normalize=CM_NORMALIZED,
                                      title='Confusion matrix, ' + phase)
                
                # Save confusion matrix figure
                fig3_filename = 'cm' + phase + '_' + filename_pre + '.pdf'
                fig3.set_size_inches(FIG_HEIGHT, FIG_WIDTH)
                fig3.savefig(os.path.join(out_path, fig3_filename), bbox_inches='tight', dpi=FIG_DPI)
                
                # Also save as jpg, 5-1-2020
                fig3_filename_jpg = 'cm' + phase + '_' + filename_pre + '.jpg'
                fig3.savefig(os.path.join(out_path, fig3_filename_jpg), bbox_inches='tight', dpi=FIG_DPI)
            
                # Display confusion matrix analysis
                cm2 = pycm.ConfusionMatrix(actual_vector=y_actu, predict_vector=y_pred) # Create CM From Data
    #            cm2 = pycm.ConfusionMatrix(matrix={"Class1": {"Class1": 1, "Class2":2}, "Class2": {"Class1": 0, "Class2": 5}}) # Create CM Directly
                cm2 # line output: pycm.ConfusionMatrix(classes: ['Class1', 'Class2'])
                print(cm2)
                
            
        plt.ioff()
        plt.show()
예제 #4
0
    #    #M_out = np.flip(M_out, axis=0)
    #    print('X shape: ', X.shape)

    #    # Read image with pydicom
    #    filepath = mat.uigetfile()
    #    foldername = os.path.dirname(filepath)
    #    ds = pydicom.dcmread(filepath)  # plan dataset
    #    spacing2d = ds.PixelSpacing
    #    spacing = [spacing2d[0], spacing2d[1], ds.SliceThickness]
    #    origin = ds.ImagePositionPatient
    #    size_image = [ds.Columns, ds.Rows, ds.NumberOfFrames]
    #    X = ds.pixel_array
    #    X = np.transpose(X, axes=(2,1,0)) # (z, y, x) -> (x, y, z)

    # Read NRRD image with pynrrd
    filepath = mat.uigetfile()
    foldername = os.path.dirname(filepath)
    data, header = nrrd.read(filepath)
    spacing = np.diagonal(header['space directions'])
    size_image = np.shape(data)
    origin = header['space origin']
    X = data

    #    print('X shape: ', X.shape)

    # No upsample or make isometric
    new_shape = size_image
    new_spacing = spacing

    #    # Make image isometric and Upsample image
    #    upsample_factor_iso = spacing/np.min(spacing)
예제 #5
0
파일: elhnet.py 프로젝트: jso111/ELHnet
    scores = np.mean(tile_scores, axis=(1, 2))

    return scores


def preprocess(X):
    # Perform mean subtraction and normalization using per image statistics to turn pixel values into z-scores
    X = X - np.mean(X)
    X /= np.std(X)

    return X


if __name__ == '__main__':
    # ask user to select an image
    filename = mat.uigetfile()

    # read image
    X = plt.imread(filename)
    if len(np.shape(X)) == 3:
        X = X[:, :, 0]  # convert 64x64x4 augmented image to 64x64 2-D array

    # Perform mean subtraction and normalization using per image statistics to turn pixel values into z-scores
    X = preprocess(X)

    ### Run model on user-selected ROI from input image, display, and save results
    # FIRST run %matplotlib qt
    coords = mat.pickpoint(X)  # pick center of ROI
    x, y = coords[0]
    x = np.round(x)
    y = np.round(y)
예제 #6
0
def writeDicom(image, targetfolder):
    print("Writing image:", targetfolder)

    sitk.WriteImage(image, targetfolder)


#def showDicom(image):
#    sitk.Show( image, "Dicom Series" , debugOn=True)
#

if __name__ == '__main__':

    # ask user to select folder containing DICOM image series
    print("Test modifyNRRD.py: select NRRD file")
    file_path = mat.uigetfile()

    # read image
    X, header = nrrd.read(
        file_path
    )  # data, assume shape is (H,W,D) <--(X,Y,Z) with horizontal flip
    print(X.shape)  # numpy array indexes (z, y, x) (height, row, column)

    # flip image horizontally (R-L), trial 1
    print("Flip images....")
    #    X_flip1 = np.fliplr(X) # flips axies 1
    #    X_flip2 = np.flip(X, axis=2)
    X_flip0 = np.flip(X, axis=0)

    # flip image horizontally, trial 2