Running conv-nets

This ipython notebook walks you through the running_template.py script.

First, we need to load the necessary python modules

In [1]:
import h5py
import tifffile as tiff
from keras.backend.common import _UID_PREFIXES

from cnn_functions import nikon_getfiles, get_image, run_models_on_directory, get_image_sizes, segment_nuclei, segment_cytoplasm, dice_jaccard_indices
from model_zoo import sparse_bn_feature_net_61x61 as cyto_fn
from model_zoo import sparse_bn_feature_net_61x61 as nuclear_fn

import os
import numpy as np
Using Theano backend.

Next, we need to specify some directory locations - namely where the home data directory is (direc_name), where the raw images are located (data_location), where to store they cytoplasm prediction images (cyto_location), where to store the nuclear prediction images (nuclear_location), and where to store the final segmentation masks (mask_location)

In [2]:
direc_name = '/home/vanvalen/DeepCell2/validation_data/HeLa/'
data_location = os.path.join(direc_name, 'RawImages')

cyto_location = os.path.join(direc_name, 'Cytoplasm')
nuclear_location = os.path.join(direc_name, 'Nuclear')
mask_location = os.path.join(direc_name, 'Masks')

Next, we need to define the channel names. In this case, the cytoplasm network takes in phase and nuclear marker (farred) images. The channel names have to be present in the file names. We also need to specify the directory the conv-net parameter files live in and what the file names are.

In [3]:
cyto_channel_names = ['phase', 'farred']
nuclear_channel_names = ['farred']

trained_network_cyto_directory = "/home/vanvalen/DeepCell2/trained_networks/HeLa/"
trained_network_nuclear_directory = "/home/vanvalen/DeepCell2/trained_networks/Nuclear"

cyto_prefix = "2016-07-12_HeLa_all_61x61_bn_feature_net_61x61_"
nuclear_prefix = "2016-07-12_nuclei_all_61x61_bn_feature_net_61x61_"

We are using a network that takes in 61x61 images in this example. We need to manually feed in the window size (the number of pixels sampled around each pixels). We also need to specify the image size. Because these images are large, we will end up chopping the image in quarters, processing each quarter, and then piece the image back together

In [4]:
win_cyto = 30
win_nuclear = 30

image_size_x, image_size_y = get_image_sizes(data_location, nuclear_channel_names)
image_size_x /= 2
image_size_y /= 2

Now we need to load the weights for the networks. Remember we make use of two networks - one for the cytoplasm and another for the nucleus. Because we use model parallelism, we have 5 networks for each segmentation task.

In [5]:
list_of_cyto_weights = []
for j in xrange(5):
	cyto_weights = os.path.join(trained_network_cyto_directory,  cyto_prefix + str(j) + ".h5")
	list_of_cyto_weights += [cyto_weights]

list_of_nuclear_weights = []
for j in xrange(5):
	nuclear_weights = os.path.join(trained_network_nuclear_directory,  nuclear_prefix + str(j) + ".h5")
	list_of_nuclear_weights += [nuclear_weights]

Next, we run all our networks on all the files in our directory.

In [6]:
cytoplasm_predictions = run_models_on_directory(data_location, cyto_channel_names, cyto_location, model_fn = cyto_fn, 
	list_of_weights = list_of_cyto_weights, image_size_x = image_size_x, image_size_y = image_size_y, 
	win_x = win_cyto, win_y = win_cyto, std = False, split = False)

nuclear_predictions = run_models_on_directory(data_location, nuclear_channel_names, nuclear_location, model_fn = nuclear_fn, 
	list_of_weights = list_of_nuclear_weights, image_size_x = image_size_x, image_size_y = image_size_y, 
	win_x = win_nuclear, win_y = win_nuclear, std = False, split = False)
Processing image 1 of 1
Processing image 1 of 1
Processing image 1 of 1
Processing image 1 of 1
Processing image 1 of 1
Processing image 1 of 1
Processing image 1 of 1
Processing image 1 of 1
Processing image 1 of 1
Processing image 1 of 1

Next, we need to refine the neural network predictions to create segmentation masks. The smoothing and num_iters parameters control the active contour refinement process.

In [7]:
nuclear_masks = segment_nuclei(nuclear_predictions, mask_location = mask_location, threshold = 0.75, area_threshold = 100, solidity_threshold = 0.75, eccentricity_threshold = 0.95)
cytoplasm_masks = segment_cytoplasm(cytoplasm_predictions, nuclear_masks = nuclear_masks, mask_location = mask_location, smoothing = 1, num_iters = 120)

With the masks computed, if a reference segmentation is available, we can test our conv-net segmentation against them to compute the Jaccard and Dice indices.

In [8]:
direc_val = os.path.join(direc_name, 'Validation')
imglist_val = nikon_getfiles(direc_val, 'validation_interior')

val_name = os.path.join(direc_val, imglist_val[0]) 
val = get_image(val_name)
val = val[win_cyto:-win_cyto,win_cyto:-win_cyto]
cyto = cytoplasm_masks[0,win_cyto:-win_cyto,win_cyto:-win_cyto]
nuc = nuclear_masks[0,win_cyto:-win_cyto,win_cyto:-win_cyto]

dice_jaccard_indices(cyto, val, nuc)
Jaccard index is 0.84462 +/- 0.0107597496164
Dice index is 0.914696973088 +/- 0.00655002244584
Out[8]:
(0.84462011, 0.91469697308829423)