Skip to content

Commit

Permalink
Move RandomWalkerAlgorithm from CellProfiler to CellProfiler-plugins (r…
Browse files Browse the repository at this point in the history
…esolves CellProfiler#14).

Additionally, enables Travis (resolves CellProfiler#9).
  • Loading branch information
mcquin committed Jun 19, 2017
1 parent 0cf9235 commit dbb3e1a
Show file tree
Hide file tree
Showing 5 changed files with 257 additions and 0 deletions.
24 changes: 24 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
addons:
apt:
packages:
- libhdf5-serial-dev
- python-pip
apt: true
directories: $HOME/.cache/pip
dist: trusty
env:
- LC_ALL="en_US.UTF-8" CP_MYSQL_TEST_HOST="127.0.0.1" CP_MYSQL_TEST_USER="root" CP_MYSQL_TEST_PASSWORD=""
install:
- pip install --upgrade pip
- pip install --upgrade cython
- pip install --upgrade joblib
- pip install --upgrade numpy
- pip install --upgrade scipy
- pip install --editable git+https://github.com/CellProfiler/CellProfiler.git#egg=CellProfiler
- pip freeze
language: python
notifications:
email: false
python: 2.7
script: pytest
sudo: false
114 changes: 114 additions & 0 deletions randomwalkeralgorithm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# coding=utf-8

"""
Random walker algorithm
Single-channel images can be two-or-three-dimensional.
"""

import numpy
import skimage.color
import skimage.measure
import skimage.segmentation

import cellprofiler.module
import cellprofiler.object
import cellprofiler.setting


class RandomWalkerAlgorithm(cellprofiler.module.ImageSegmentation):
module_name = "Random walker algorithm"

variable_revision_number = 1

def create_settings(self):
super(RandomWalkerAlgorithm, self).create_settings()

self.first_phase = cellprofiler.setting.Float(
doc="First phase demarcates an image’s first phase.",
text="First phase",
value=0.5
)

self.second_phase = cellprofiler.setting.Float(
doc="Second phase demarcates an image’s second phase.",
text="Second phase",
value=0.5
)

self.beta = cellprofiler.setting.Float(
doc="""
Beta is the penalization coefficient for the random walker motion. Increasing the penalization
coefficient increases the difficulty of the diffusion. Likewise, decreasing the penalization coefficient
decreases the difficulty of the diffusion.
""",
text="Beta",
value=130.0
)

def settings(self):
__settings__ = super(RandomWalkerAlgorithm, self).settings()

return __settings__ + [
self.first_phase,
self.second_phase,
self.beta
]

def visible_settings(self):
__settings__ = super(RandomWalkerAlgorithm, self).settings()

return __settings__ + [
self.first_phase,
self.second_phase,
self.beta
]

def run(self, workspace):
x_name = self.x_name.value

y_name = self.y_name.value

images = workspace.image_set

x = images.get_image(x_name)

x_data = x.pixel_data

if x.multichannel:
x_data = skimage.color.rgb2gray(x_data)

labels_data = numpy.zeros_like(x_data, numpy.uint8)

labels_data[x_data > self.first_phase.value] = 1

labels_data[x_data < self.second_phase.value] = 2

y_data = skimage.segmentation.random_walker(
beta=self.beta.value,
data=x_data,
labels=labels_data,
multichannel=False,
spacing=x.spacing
)

y_data = skimage.measure.label(y_data)

objects = cellprofiler.object.Objects()

objects.segmented = y_data

objects.parent_image = x

workspace.object_set.add_objects(objects, y_name)

self.add_measurements(workspace)

if self.show_window:
workspace.display_data.x_data = x_data

workspace.display_data.y_data = y_data

workspace.display_data.dimensions = x.dimensions
Empty file added tests/__init__.py
Empty file.
68 changes: 68 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import cellprofiler.image
import cellprofiler.measurement
import cellprofiler.object
import cellprofiler.pipeline
import cellprofiler.workspace
import numpy
import skimage.data
import pytest


@pytest.fixture(
scope="module",
params=[
(skimage.data.camera()[0:128, 0:128], 2),
(skimage.data.astronaut()[0:128, 0:128, :], 2),
(numpy.tile(skimage.data.camera()[0:32, 0:32], (2, 1)).reshape(2, 32, 32), 3)
],
ids=[
"grayscale_image",
"multichannel_image",
"grayscale_volume"
]
)
def image(request):
data, dimensions = request.param

return cellprofiler.image.Image(image=data, dimensions=dimensions)


@pytest.fixture(scope="function")
def image_set(image, image_set_list):
image_set = image_set_list.get_image_set(0)

image_set.add("example", image)

return image_set


@pytest.fixture(scope="function")
def image_set_list():
return cellprofiler.image.ImageSetList()


@pytest.fixture(scope="function")
def measurements():
return cellprofiler.measurement.Measurements()


@pytest.fixture(scope="module")
def module(request):
instance = getattr(request.module, "instance")

return instance


@pytest.fixture(scope="function")
def object_set():
return cellprofiler.object.ObjectSet()


@pytest.fixture(scope="function")
def pipeline():
return cellprofiler.pipeline.Pipeline()


@pytest.fixture(scope="function")
def workspace(pipeline, module, image_set, object_set, measurements, image_set_list):
return cellprofiler.workspace.Workspace(pipeline, module, image_set, object_set, measurements, image_set_list)
51 changes: 51 additions & 0 deletions tests/test_randomwalkeralgorithm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import cellprofiler.preferences
import numpy
import numpy.testing
import skimage.color
import skimage.measure
import skimage.segmentation

import randomwalkeralgorithm

cellprofiler.preferences.set_headless()

instance = randomwalkeralgorithm.RandomWalkerAlgorithm()


def test_run(image, module, workspace):
module.x_name.value = "example"

module.y_name.value = "RandomWalkerAlgorithm"

module.first_phase.value = 0.5

module.second_phase.value = 0.5

module.beta.value = 130.0

module.run(workspace)

x_data = image.pixel_data

if image.multichannel:
x_data = skimage.color.rgb2gray(x_data)

labels_data = numpy.zeros_like(x_data, numpy.uint)

labels_data[x_data < 0.5] = 1

labels_data[x_data > 0.5] = 2

expected = skimage.segmentation.random_walker(
beta=130.0,
data=x_data,
labels=labels_data,
multichannel=False,
spacing=image.spacing
)

expected = skimage.measure.label(expected)

actual = workspace.get_objects("RandomWalkerAlgorithm")

numpy.testing.assert_array_equal(expected, actual.segmented)

0 comments on commit dbb3e1a

Please sign in to comment.