Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed: execution error of command.py with multiple parameters #4

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -89,3 +89,15 @@ ENV/
.ropeproject

.DS_Store

# imagingdata
data/

# output
output/

# jupyter-notebook
ipynb/

# ~
*~
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -13,6 +13,10 @@ RUN conda install matplotlib==1.5.1 \
pypng==0.0.18 mahotas==1.4.1 opencv-python==3.2.0.7 \
git+https://github.com/jfrelinger/cython-munkres-wrapper \
jupyter
RUN pip install numba notebook==5.4.1
RUN pip install fast-histogram



EXPOSE 8888
WORKDIR /home
3 changes: 0 additions & 3 deletions celltk/caller.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import argparse
from os.path import join, isdir, exists
from glob import glob
@@ -7,7 +6,6 @@
import yaml
import multiprocessing
from utils.file_io import make_dirs
print 'test celltk'
import sys

logger = logging.getLogger(__name__)
@@ -83,7 +81,6 @@ def run_operation(output_dir, operation):
functions, params, images, labels, output = parse_operation(operation)
inputs = prepare_path_list(images, output_dir)
logger.info(inputs)

inputs_labels = prepare_path_list(labels, output_dir)
output = join(output_dir, output) if output else output_dir
caller = _retrieve_caller_based_on_function(functions[0])
2 changes: 1 addition & 1 deletion celltk/labeledarray/labeledarray/labeledarray.py
Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@ def _label2idx(self, item):
if boolarr.all():
return (slice(None, None, None), ) + (slice(None, None, None), ) * (self.ndim - 1)
minidx = min(tidx) if min(tidx) > 0 else None
maxidx = max(tidx) if max(tidx) < self.shape[0] - 1 else None
maxidx = max(tidx)+1 if max(tidx)+1 < self.shape[0] else None
if boolarr.sum() > 1:
return (slice(minidx, maxidx, None), ) + (slice(None, None, None), ) * (self.ndim - 1)

2 changes: 1 addition & 1 deletion celltk/postprocess.py
Original file line number Diff line number Diff line change
@@ -85,7 +85,7 @@ def main():
parser.add_argument("-l", "--labels", help="labels", nargs="+")
parser.add_argument("-o", "--output", help="output directory", type=str, default='temp')
parser.add_argument("-f", "--functions", help="functions", nargs="+")
parser.add_argument("-p", "--param", nargs="*", help="parameters", default=[])
parser.add_argument('-p', '--param', nargs='+', help='parameters', action='append')
args = parser.parse_args()

if args.functions is None:
4 changes: 3 additions & 1 deletion celltk/preprocess.py
Original file line number Diff line number Diff line change
@@ -37,7 +37,9 @@ def main():
parser.add_argument("-i", "--input", help="images", nargs="*")
parser.add_argument("-o", "--output", help="output directory", type=str, default='temp')
parser.add_argument("-f", "--functions", help="functions", nargs="*")
parser.add_argument("-p", "--param", nargs="*", help="parameters", default=[])
parser.add_argument('-p', '--param', nargs='+', help='parameters', action='append')
# parser.add_argument("-p", "--param", nargs="*", help="parameters", default=[])

args = parser.parse_args()

if args.functions is None:
82 changes: 43 additions & 39 deletions celltk/preprocess_operation.py
Original file line number Diff line number Diff line change
@@ -16,17 +16,17 @@
from utils.global_holder import holder
from utils.mi_align import calc_jitters_multiple, calc_crop_coordinates
from utils.shading_correction import retrieve_ff_ref
import cv2
from utils.background_subtractor import subtract_background_rolling_ball
from scipy.ndimage.filters import gaussian_filter

logger = logging.getLogger(__name__)
np.random.seed(0)


def gaussian_blur(img, SIGMA=3):
img = gaussian_filter(img, sigma=SIGMA)
return img


def gaussian_laplace(img, SIGMA=2.5, NEG=False):
if NEG:
img = -calc_lapgauss(img, SIGMA)
@@ -50,14 +50,15 @@ def background_subtraction_wavelet_hazen(img, THRES=100, ITER=5, WLEVEL=6, OFFSE
img = img - back
return convert_positive(img, OFFSET)

def background_subtraction_rolling_ball_hazen(img, RADIUS=100, SIGMA=3, OFFSET=50):

def rolling_ball(img, RADIUS=100, SIGMA=3, OFFSET=50):
"""Rolling ball background subtraction.
"""
back = rolling_ball_subtraction_hazen(img.astype(np.float), RADIUS)
img = img - back
#return img
return convert_positive(img, OFFSET)


def n4_illum_correction(img, RATIO=1.5, FILTERINGSIZE=50):
"""
Implementation of the N4 bias field correction algorithm.
@@ -109,33 +110,6 @@ def align(img, CROP=0.05):
return img[jt[0]:jt[1], jt[2]:jt[3], :]


def align2(img, CROP=0.05):
"""
CROP (float): crop images beforehand. When set to 0.05, 5% of each edges are cropped.
"""
if not hasattr(holder, "align"):
if isinstance(holder.inputs[0], list) or isinstance(holder.inputs[0], tuple):
inputs = [i[0] for i in holder.inputs]
else:
inputs = holder.inputs

img0 = imread(inputs[0])

(ch, cw) = [int(CROP * i) for i in img0.shape]
ch = None if ch == 0 else ch
cw = None if cw == 0 else cw

jitters = calc_jitters_multiple(inputs, ch, cw)
holder.align = calc_crop_coordinates(jitters, img0.shape)
logger.debug('holder.align set to {0}'.format(holder.align))
jt = holder.align[holder.frame]
logger.debug('Jitter: {0}'.format(jt))
if img.ndim == 2:
return img[jt[0]:jt[1], jt[2]:jt[3]]
if img.ndim == 3:
return img[jt[0]:jt[1], jt[2]:jt[3], :]


def flatfield_references(img, ff_paths=['Pos0/img00.tif', 'Pos1/img01.tif'], exp_corr=False):
"""
Use empty images for background subtraction and illumination bias correction.
@@ -227,6 +201,19 @@ def correct_shade(img, ref, darkref, ch):
img = correct_shade(img, ref, darkref, ch)
return img

def correct_uneven_illumination(img, bkgimg='Pos1/min_stack.tif'):
'''
correct_uneven_illumination
bkgimg is background image such as blank image or minimum projection result.
'''
img = img.astype(np.float)
bg = gaussian_blur(imread(bkgimg), 3)
bg = bg.astype(np.float)
d0 = img - bg
d0[d0 < 0] = 0
m_bg = 1 / (bg / bg.max()) # nega image of background
img = d0 * m_bg
return img

def background_subtraction_wavelet(img, level=7, OFFSET=10):
'''
@@ -262,11 +249,28 @@ def stitch_images(img, POINTS=[(0,0),(0,0),(0,0),(0,0)]):
img = np_arithmetic(img, 'max')
return img

def rolling_ball(img, RADIUS=30):

img = (img/256).astype('uint8')
img = subtract_background_rolling_ball(img, RADIUS, light_background=False,\
use_paraboloid=False, do_presmooth=True, create_background=False)
return img


def bleedthourh_correction(img, BT=0.0):
img0 = img[:, :, 0].astype(np.float)
img1 = img[:, :, 1].astype(np.float)
img0 = img0 - img1 * BT
return img0

def deep_unet(img, weight_path, region=1):
""" Generates a probability map of cells using the UNet algorithm.

Args:
img (numpy.ndarray): image that will be segmented
weight_path (string): path to weights file in .hdf5 format, can either bea local path or url.
region (int): determines if each image will be saved individually (region =1) or
setting region as None will save a stack of float32 images.
Returns:
pimg (numpy.ndarray): probability map image

"""
from utils.unet_predict import predict
from utils.file_io import LocalPath
from utils.global_holder import holder
with LocalPath(weight_path) as wpath:
pimg = predict(holder.path, wpath)
pimg = np.moveaxis(pimg, 0, -1)
return pimg[:, :, region]
3 changes: 1 addition & 2 deletions celltk/segment.py
Original file line number Diff line number Diff line change
@@ -60,11 +60,10 @@ def main():
parser.add_argument("-o", "--output", help="output directory",
type=str, default='temp')
parser.add_argument("-f", "--functions", help="functions", nargs="*", default=None)
parser.add_argument("-p", "--param", nargs="*", help="parameters", default=[])
parser.add_argument('-p', '--param', nargs='+', help='parameters', action='append')
args = parser.parse_args()

params = ParamParser(args.param).run()

if args.functions is None:
print help(segment_operation)
return
23 changes: 3 additions & 20 deletions celltk/segment_operation.py
Original file line number Diff line number Diff line change
@@ -44,7 +44,7 @@ def adaptive_thres_two(img, FIL1=10, FIL2=100, R1=100, R2=100):
"""
bw = adaptive_thresh(img, R=R1, FILTERINGSIZE=FIL1)
foreground = adaptive_thresh(img, R=R2, FILTERINGSIZE=FIL2)
bw[-foreground] = 0
bw[~foreground] = 0
return label(bw)


@@ -54,7 +54,7 @@ def adaptive_thres_otsu(img, FIL1=4, R1=1):
"""
bw = adaptive_thresh(img, R1, FIL1)
foreground = global_otsu(img) > 0
bw[-foreground] = 0
bw[~foreground] = 0
return label(bw)


@@ -67,7 +67,7 @@ def watershed_labels(labels, REG=10):

def lap_peak_local(img, separation=10, percentile=64, min_sigma=2, max_sigma=5, num_sigma=10):
sigma_list = np.linspace(min_sigma, max_sigma, num_sigma)
gl_images = [-gaussian_laplace(img, s) * s ** 2 for s in sigma_list]
gl_images = [~gaussian_laplace(img, s) * s ** 2 for s in sigma_list]
image_cube = np.dstack(gl_images)
max_image = np.max(image_cube, axis=2)
coords = grey_dilation(max_image, separation=separation, percentile=percentile)
@@ -81,20 +81,3 @@ def mark_pos(im, coords):
return label(binary_dilation(bw, np.ones((3, 3))))


def deepcell(img, model_path, weight_path, padding=30, rad=[10, 30]):
"""
model_path and weight_path can be either local path or url.
"""
from utils.tf_deepcell.predict import predict
from segment import clean_labels
from subdetect_operation import propagate_multisnakes
from utils.file_io import LocalPath
from utils.global_holder import holder
with LocalPath(model_path) as mpath, LocalPath(weight_path) as wpath:
pimg = predict(holder.path, mpath, wpath)
cell = pimg[1] > pimg[0] * 100
cell[pimg[1] < pimg[2] * 100] = False
cell = np.pad(cell, padding, 'constant')
print cell.shape, img.shape
cimg = propagate_multisnakes(label(cell), img, NITER=2, lambda2=30)
return clean_labels(cimg, rad=rad)
2 changes: 1 addition & 1 deletion celltk/subdetect.py
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ def main():
parser.add_argument("-o", "--output", help="output directory",
type=str, default='temp')
parser.add_argument("-f", "--functions", help="functions", nargs="+")
parser.add_argument("-p", "--param", nargs="*", help="parameters", default=[])
parser.add_argument('-p', '--param', nargs='+', help='parameters', action='append')
args = parser.parse_args()

if args.functions is None:
69 changes: 68 additions & 1 deletion celltk/subdetect_operation.py
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
import numpy as np
from scipy.ndimage import morphology
from skimage.morphology import remove_small_objects
from utils.labels_handling import convert_labels
from utils.subdetect_utils import label_high_pass, label_nearest

np.random.seed(0)

@@ -130,7 +132,7 @@ def morphological(labels, func='grey_opening', size=3, iterations=1):
def watershed_divide(labels, regmax=10, min_size=100):
"""
divide objects in labels with watershed segmentation.
regmax:
regmax:
min_size: objects smaller than this size will not be divided.
"""
from utils.subdetect_utils import watershed_labels
@@ -141,3 +143,68 @@ def watershed_divide(labels, regmax=10, min_size=100):
ws_large += labels.max()
ws_large[ws_large == labels.max()] = 0
return labels + ws_large


def cytoplasm_levelset(labels, img, niter=20, dt=-0.5, thres=0.5):
""" Segment cytoplasm from supplied nuclear labels and probability map
Expand using level sets method from nuclei to membrane.
Uses an implementation of Level set method. See:
https://wiseodd.github.io/techblog/2016/11/05/levelset-method/

Args:
labels (numpy.ndarray): nuclear mask labels
img (numpy.ndarray): probability map
niter (int): step size to expand mask, number of iterations to run the levelset algorithm
dt (float): negative values for porgation, positive values for shrinking
thres (float): threshold of probability value to extend the nuclear mask to

Returns:
cytolabels (numpy.ndarray): cytoplasm mask labels

"""
from skimage.morphology import closing, disk, remove_small_holes
from utils.dlevel_set import dlevel_set
phi = labels.copy()
phi[labels == 0] = 1
phi[labels > 0] = -1

outlines = img.copy()
outlines = -outlines
outlines = outlines - outlines.min()
outlines = outlines/outlines.max()

mask = outlines < thres
phi = dlevel_set(phi, outlines, niter=niter, dt=dt, mask=mask)

cytolabels = label(remove_small_holes(label(phi < 0)))
cytolabels = closing(cytolabels, disk(3))

temp = cytolabels.copy()
temp[labels == 0] = 0
cytolabels = convert_labels(temp, labels, cytolabels)
return cytolabels

def segment_bacteria(nuc, img, slen=3, SIGMA=0.5,THRES=100, CLOSE=20, THRESCHANGE=1000, MINAREA=5):
""" Segment bacteria and assign to closest nucleus

Args:
nuc (numpy.ndarray): nuclear mask labels
img (numpy.ndarray): image in bacterial channel
slen (int): Size of Gaussian kernel
SIGMA (float): Standard deviation for Gaussian kernel
THRES (int): Threshold pixel intensity fo real signal
CLOSE (int): Radius for disk used to return morphological closing of the image (dilation followed by erosion to remove dark spots and connect bright cracks)
THRESCHANGE (int): argument unnecessary?
MINAREA (int): minimum area in pixels for a bacterium

Returns:
labels (numpy.ndarray[np.uint16]): bacterial mask labels

"""
labels = label_high_pass(img, slen=slen, SIGMA=SIGMA, THRES=THRES, CLOSE=3)
if labels.any():
labels, comb, nuc_prop, nuc_loc = label_nearest(img, labels, nuc)
from skimage.morphology import remove_small_objects
labels = remove_small_objects(labels, MINAREA)
return labels.astype(np.uint16)

2 changes: 1 addition & 1 deletion celltk/track.py
Original file line number Diff line number Diff line change
@@ -57,7 +57,7 @@ def main():
parser.add_argument("-o", "--output", help="output directory",
type=str, default='temp')
parser.add_argument("-f", "--functions", help="functions", nargs="+")
parser.add_argument("-p", "--param", nargs="*", help="parameters", default=[])
parser.add_argument('-p', '--param', nargs='+', help='parameters', action='append')
args = parser.parse_args()

if args.functions is None:
2 changes: 1 addition & 1 deletion celltk/track_operation.py
Original file line number Diff line number Diff line change
@@ -120,7 +120,7 @@ def run_lap(img0, img1, labels0, labels1, DISPLACEMENT=30, MASSTHRES=0.2):


def track_neck_cut(img0, img1, labels0, labels1, DISPLACEMENT=10, MASSTHRES=0.2,
EDGELEN=5, THRES_ANGLE=180, WSLIMIT=False, SMALL_RAD=3, CANDS_LIMIT=300):
EDGELEN=5, THRES_ANGLE=180, WSLIMIT=False, SMALL_RAD=None, CANDS_LIMIT=300):
"""
Adaptive segmentation by using tracking informaiton.
Separate two objects by making a cut at the deflection. For each points on the outline,
Loading