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

Img proc api #63

Open
wants to merge 35 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
2970091
DEV: Moved mathops.py and test_img_proc from skxray to vttools
Apr 8, 2015
af219e2
DEV: Reduced the included funcs to only arith funcs specific to VisTr…
Apr 9, 2015
221fb0d
DEV: Added __init__ to vttools tests folder. Can now access tests
Apr 10, 2015
d8c978a
TST: Img arith tool test. Changed tool location and refs to srch vttool
Apr 10, 2015
ff10b4a
DEV: Mod to arith_custom docs. Removed additional operators.
Apr 13, 2015
9be03ce
DEV: Changed data inputs to x1 and x2. Completed docstrings for funcs.
Apr 13, 2015
4cf2f9f
DEV: Renamed functions so they're simpler and more straight forward.
Apr 13, 2015
5b2e3a2
DEV: Transferred test funcs for arith tools for VT from skxray.
Apr 13, 2015
adf036f
DEV: Updated functions in image_proc.py after transfer from skxray
Apr 14, 2015
1b7a073
TST: Updated basic arith test function after img_proc name changes
Apr 14, 2015
bbed6dc
TST: Updated test for arith_expression after func name change in vttools
Apr 14, 2015
9822c1f
DOC: Updated input params docstrings, simplifying them.
Apr 14, 2015
fcc8d22
TST: Tested and verified img_proc tst funcs using nose, coverage.
Apr 14, 2015
bff1406
DEV: Moved mathops.py and test_img_proc from skxray to vttools
Apr 8, 2015
a699039
DEV: Reduced the included funcs to only arith funcs specific to VisTr…
Apr 9, 2015
cf06549
DEV: Added __init__ to vttools tests folder. Can now access tests
Apr 10, 2015
102feb3
TST: Img arith tool test. Changed tool location and refs to srch vttool
Apr 10, 2015
98c3f36
DEV: Mod to arith_custom docs. Removed additional operators.
Apr 13, 2015
5545161
DEV: Changed data inputs to x1 and x2. Completed docstrings for funcs.
Apr 13, 2015
f4d9a17
DEV: Renamed functions so they're simpler and more straight forward.
Apr 13, 2015
91a4547
DEV: Transferred test funcs for arith tools for VT from skxray.
Apr 13, 2015
72f0463
DEV: Updated functions in image_proc.py after transfer from skxray
Apr 14, 2015
d51e33f
TST: Updated basic arith test function after img_proc name changes
Apr 14, 2015
bef01aa
TST: Updated test for arith_expression after func name change in vttools
Apr 14, 2015
ffa4cd2
DOC: Updated input params docstrings, simplifying them.
Apr 14, 2015
69e81a0
TST: Tested and verified img_proc tst funcs using nose, coverage.
Apr 14, 2015
25fc89c
DOC, MNT: Edits to be consistent with np and pep8
ericdill Apr 15, 2015
08c0aab
Merge branch 'master' of github.com:Nikea/VTTools into img_proc_math
Jun 15, 2015
bdbe90d
Merge remote-tracking branch 'dill/img_proc_math' into img_proc_math
Jun 15, 2015
062059f
DEV: Updated init.py to properly include all img proc arithmetic funcs
Jun 21, 2015
ef51305
DEV: Changed test import statement to reflect img_proc to arithmetic …
Jun 21, 2015
03eaf66
FIX: Removed HTML folder which was inadvertently added at some point.
Jun 22, 2015
4007ce2
DOC: Updated and corrected doc for arith-expr referencing lmfit.asteval
Jun 23, 2015
f67a3bb
DOC: Added TODO that docs for logical func need to be updated after s…
Jun 23, 2015
0c1ad48
DEV: Added image processing API tools to init.py for VisTrails access
Jun 24, 2015
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,6 @@ docs/_build/

# coverage
cover/

# generated by various tools
html/
48 changes: 48 additions & 0 deletions doc/resource/user-guide/image.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
Image Operations in VisTrails
-----------------------------

"arithmetic" VisTrails module
=============================
The VisTrails module `arithmetic` enables basic arithmetic for image processing
and data analysis. The function is capable of applying the basic arithmetic
operations (addition, subtraction, multiplication and division) to two data set
arrays, two constants, or an array and a constant.

**Addition.** The addition of EITHER two images or volume data sets, OR an
image/data set and a value. This function is typically used for offset purposes,
or basic recombination of several isolated materials or phases into a single
segmented volume.

**Subtraction.** Enables the subtraction of EITHER one image or volume data set
from another, OR reduction of all values in an image/data set by a set value.
This function is typically used for offset purposes, or basic isolation of
objects or materials/phases in a data set.

**Multiplication.** Enables the multiplication of input 1 (x1) by input 2 (x2).
The inputs can be of any valid numpy data type (e.g. an image or volume data a
fixed, constant, value). This function is typically used for offset purposes
(rescaling), or for assigning values in the generation of a labelfield identifying
objects or materials/phases in a data set.

**Division.** Enables the division of input 1 (x1, numerator) by input 2 (x2,
denominator). The inputs can be of any valid numpy data type (e.g. an image or
volume data a fixed, constant, value). Basic tests are included in the division
function which test for, and ensure that division by zero does not occur. This
function is typically used for offset purposes (rescaling, normalization).

"arithmetic_expression" VisTrails module
========================================
The VisTrails module `arithmetic_expression` enables the use of custom
expressions to evaluate up to 8 input variables, named A-H. This function
enables more complex arithmetic to be carried out on 2 or more (current limit
is 8) arrays or constants. The arithmetic expression is defined by the user, as
a string, and after assignment of inputs A through H the string is parsed into
the appropriate python expression and executed. Note that inputs C through H
are optional and need only be defined when desired or required.

"logical" VisTrails module
==========================
The VisTrails module `logical` enables the computation of the basic logical
operations oft used in image processing of two image or volume data sets. This
function can be used for data comparison, material isolation, noise removal,
or mask application/generation.
8 changes: 8 additions & 0 deletions vt_config/NSLS-II/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
# get modules to import
import_dict = load_config()


_black_list = ['who', 'mafromtxt', 'ndfromtxt', 'source',
'info', 'add_newdoc_ufunc', 'frombuffer',
'fromiter', 'frompyfunc', 'getbuffer',
Expand Down Expand Up @@ -103,6 +104,7 @@ def get_modules():
'scipy.special',
'scipy.stats',
'skxray.calibration',
'skxray.image_processing.arithmetic',
'skxray.correlation',
'skxray.core',
'skxray.recip',
Expand All @@ -111,7 +113,13 @@ def get_modules():
'skxray.io.save_powder_output',
'skxray.io.gsas_file_reader',
'skxray.api.diffraction',
'vttools.to_wrap.image_processing.arithmetic',
'vttools.to_wrap.fitting',
'skxray.api.image_processing.arithmetic.basic_math',
'skxray.api.image_processing.arithmetic.logic',
'skxray.api.image_processing.filtering',
'skxray.api.image_processing.morphology',
'skxray.api.image_processing.registration'
]

for mod_name in mod_targets:
Expand Down
37 changes: 36 additions & 1 deletion vttools/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,36 @@

# ######################################################################
# Copyright (c) 2014, Brookhaven Science Associates, Brookhaven #
# National Laboratory. All rights reserved. #
# #
# Redistribution and use in source and binary forms, with or without #
# modification, are permitted provided that the following conditions #
# are met: #
# #
# * Redistributions of source code must retain the above copyright #
# notice, this list of conditions and the following disclaimer. #
# #
# * Redistributions in binary form must reproduce the above copyright #
# notice this list of conditions and the following disclaimer in #
# the documentation and/or other materials provided with the #
# distribution. #
# #
# * Neither the name of the Brookhaven Science Associates, Brookhaven #
# National Laboratory nor the names of its contributors may be used #
# to endorse or promote products derived from this software without #
# specific prior written permission. #
# #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS #
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT #
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS #
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, #
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES #
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR #
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) #
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, #
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OTHERWISE) ARISING #
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE #
# POSSIBILITY OF SUCH DAMAGE. #
########################################################################
import logging
logger = logging.getLogger(__name__)
274 changes: 274 additions & 0 deletions vttools/tests/test_img_proc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
# Module for the BNL image processing project
# Developed at the NSLS-II, Brookhaven National Laboratory
# Developed by Gabriel Iltis, Sept. 2014
"""
This module contains test functions for the file-IO functions
for reading and writing data sets using the netCDF file format.

The files read and written using this function are assumed to
conform to the format specified for x-ray computed microtomorgraphy
data collected at Argonne National Laboratory, Sector 13, GSECars.
"""

import numpy as np
from numpy.testing import assert_equal, assert_raises, raises

import vttools.to_wrap.image_processing.arithmetic as img


@raises(AttributeError)
def arithmetic_helper_fails(op, x1, x2):
img.arithmetic(op, x1, x2)


def test_arithmetic_fails():
ops = ['addition', 'subtraction', 'division', 'multiplication']
x1s = [0] * len(ops)
x2s = [0] * len(ops)
for op, x1, x2 in zip(ops, x1s, x2s):
yield arithmetic_helper_fails, op, x1, x2


def test_arithmetic_basic():
"""
Test function for the image processing function: arithmetic_basic

"""
test_array_1 = np.zeros((30, 30, 30), dtype=np.int)
test_array_1[0:15, 0:15, 0:15] = 1
test_array_2 = np.zeros((30, 30, 30), dtype=np.int)
test_array_2[15:29, 15:29, 15:29] = 87
test_array_3 = np.ones((40, 30, 30), dtype='float')
test_array_3[10:20, 10:20, 10:20] = 87.4
test_array_4 = np.zeros((30, 30), dtype=np.int)
test_array_4[24:29, 24:29] = 254

test_1D_array_1 = np.zeros(100, dtype=np.int)
test_1D_array_1[0:30] = 50
test_1D_array_2 = np.zeros(50, dtype=np.int)
test_1D_array_2[20:49] = 10
test_1D_array_3 = np.ones(10, dtype='float')

test_constant_int = 5
test_constant_flt = 2.0

# Int array and int constant
add_check = test_array_1 + test_constant_int
sub_check = np.subtract(test_array_1, test_constant_int)
mult_check = np.multiply(test_array_1, test_constant_int)
div_check = np.divide(test_array_1, test_constant_int)

assert_equal(img.arithmetic('add', test_array_1, test_constant_int),
add_check)
assert_equal(img.arithmetic('subtract', test_array_1,
test_constant_int), sub_check)
assert_equal(img.arithmetic('multiply', test_array_1,
test_constant_int), mult_check)
assert_equal(img.arithmetic('divide', test_array_1, test_constant_int),
div_check)
assert_raises(FloatingPointError, img.arithmetic, 'divide', test_array_1,
test_array_1)
assert_raises(FloatingPointError, img.arithmetic, 'divide', test_array_1, 0)

# Int array and int array
add_check = test_array_1 + test_array_2
sub_check = np.subtract(test_array_1, test_array_2)
mult_check = np.multiply(test_array_1, test_array_2)

assert_equal(img.arithmetic('add', test_array_1, test_array_2),
add_check)
assert_equal(img.arithmetic('subtract', test_array_1, test_array_2),
sub_check)
assert_equal(img.arithmetic('multiply', test_array_1, test_array_2,),
mult_check)
assert_raises(FloatingPointError, img.arithmetic, 'divide', test_array_2,
test_array_1)

# Float array and float constant
add_check = test_array_3 + test_constant_flt
sub_check = np.subtract(test_array_3, test_constant_flt)
mult_check = np.multiply(test_array_3, test_constant_flt)
div_check = np.divide(test_array_3, test_constant_flt)

assert_equal(img.arithmetic('add', test_array_3, test_constant_flt),
add_check)
assert_equal(img.arithmetic('subtract', test_array_3,
test_constant_flt), sub_check)
assert_equal(img.arithmetic('multiply', test_array_3,
test_constant_flt), mult_check)
assert_equal(img.arithmetic('divide', test_array_3, test_constant_flt),
div_check)

# Float array and float array
add_check = test_array_3 + test_array_3
sub_check = np.subtract(test_array_3, test_array_3)
mult_check = np.multiply(test_array_3, test_array_3)
div_check = np.divide(test_array_3, test_array_3)

assert_equal(img.arithmetic('add', test_array_3, test_array_3),
add_check)
assert_equal(img.arithmetic('subtract', test_array_3, test_array_3,),
sub_check)
assert_equal(img.arithmetic('multiply', test_array_3, test_array_3),
mult_check)
assert_equal(img.arithmetic('divide', test_array_3, test_array_3),
div_check)
# Mixed dtypes: Int array and float array
assert_equal(img.arithmetic('add', test_array_1,
test_array_1.astype('float')).dtype, float)
# Float array and int constant
assert_equal(img.arithmetic('add', test_array_3,
test_constant_int).dtype, float)
# Int array and float constant
assert_equal(img.arithmetic('add', test_array_1,
test_constant_flt).dtype, float)
# Mismatched array sizes
assert_raises(ValueError, img.arithmetic, 'add', test_array_1,
test_array_3)


def test_arithmetic_custom():
"""
Test function for vttools.to_wrap.image_proc.arithmetic_expression,
a function that allows the inclusion of up to 8 inputs (arrays or
constants) and application of a custom expression, to simplify image
arithmetic including 2 or more objects or parameters.
"""
# TEST DATA
test_array_1 = np.zeros((90, 90, 90), dtype=np.int)
test_array_1[10:19, 10:19, 10:19] = 1
test_array_2 = np.zeros((90, 90, 90), dtype=np.int)
test_array_2[20:29, 20:29, 20:29] = 2
test_array_3 = np.zeros((90, 90, 90), dtype=np.int)
test_array_3[30:39, 30:39, 30:39] = 3
test_array_4 = np.zeros((90, 90, 90), dtype=np.int)
test_array_4[40:49, 40:49, 40:49] = 4
test_array_5 = np.zeros((90, 90, 90), dtype=np.int)
test_array_5[50:59, 50:59, 50:59] = 5
test_array_6 = np.zeros((90, 90, 90), dtype=np.int)
test_array_6[60:69, 60:69, 60:69] = 6
test_array_7 = np.zeros((90, 90, 90), dtype=np.int)
test_array_7[70:79, 70:79, 70:79] = 7
test_array_8 = np.zeros((90, 90, 90), dtype=np.int)
test_array_8[80:89, 80:89, 80:89] = 8

# Array manipulation
# -int only
result = (test_array_1 + test_array_2 + test_array_3 + test_array_4 +
test_array_5 + test_array_6 + test_array_7 + test_array_8)

assert_equal(img.arithmetic_expression('A+B+C+D+E+F+G+H', test_array_1,
test_array_2, test_array_3,
test_array_4, test_array_5,
test_array_6, test_array_7,
test_array_8), result)

# -float only
result = ((test_array_1.astype('float') + 3.5) +
(test_array_3.astype('float') / 2.0) -
test_array_4.astype('float'))

assert_equal(img.arithmetic_expression('(A+B)+(C/D)-E',
test_array_1.astype('float'), 3.5,
test_array_3.astype('float'), 2.0,
test_array_4.astype('float')),
result)

# -mixed int and float
result = ((test_array_1 + 3.5) + (test_array_3.astype('float') / 2) -
test_array_4)

assert_equal(img.arithmetic_expression('(A+B)+(C/D)-E', test_array_1, 3.5,
test_array_3.astype('float'), 2,
test_array_4.astype('float')),
result)

assert_equal(img.arithmetic_expression('(A+B)+(C/D)-E', test_array_1, 3.5,
test_array_3.astype('float'), 2,
test_array_4.astype('float')).dtype,
float)


def test_logical():
"""
Test function for mathops.logic_basic, a function that allows for
logical operations to be performed on one or two arrays or constants
depending on the type of operation.
For example:
logical not only takes one object, and returns the inverse, while the
other operations provide a comparison of two objects).
"""
# TEST DATA
test_array_1 = np.zeros((90, 90, 90), dtype=np.int)
test_array_1[0:39, 0:39, 0:39] = 1
test_array_2 = np.zeros((90, 90, 90), dtype=np.int)
test_array_2[20:79, 20:79, 20:79] = 2
test_array_3 = np.zeros((90, 90, 90), dtype=np.int)
test_array_3[40:89, 40:89, 40:89] = 3

# and
assert_equal(img.logical('and', test_array_1, test_array_1), test_array_1)

test_result = img.logical('and', test_array_1, test_array_2)
assert_equal(test_result[20:39, 20:39, 20:39], True)
assert_equal(test_result.sum(), ((39-20)**3))

assert_equal(img.logical('and', test_array_1, test_array_3), False)

# or
assert_equal(img.logical('or', test_array_1, test_array_1), test_array_1)

assert_equal(img.logical('or', test_array_1, test_array_2).sum(),
(test_array_1.sum() + test_array_2.sum() / 2 -
np.logical_and(test_array_1, test_array_2).sum()))

test_result = img.logical('or', test_array_1, test_array_3)
assert_equal(test_result.sum(), (test_array_1.sum() + test_array_3.sum() /
test_array_3.max()))

# not
assert_equal(img.logical('not', test_array_1).sum(),
(90**3-test_array_1.sum()))

assert_equal(img.logical('not', test_array_3).sum(),
(90**3-(test_array_3.sum()/test_array_3.max())))

# xor
assert_equal(img.logical('xor', test_array_1, test_array_1),
np.zeros((90, 90, 90), dtype=np.int))

assert_equal(img.logical('xor', test_array_1, test_array_2).sum(),
((test_array_1.sum() + test_array_2.sum() / 2) -
(2 * np.logical_and(test_array_1, test_array_2).sum())))

# nand
assert_equal(img.logical('nand', test_array_1, test_array_1),
np.logical_not(test_array_1))

test_result = img.logical('nand', test_array_1, test_array_2)
assert_equal(test_result[20:39, 20:39, 20:39], False)

# nor
assert_equal(img.logical('nor', test_array_1, test_array_1),
np.logical_not(test_array_1))
assert_equal(img.logical('nor', test_array_1, test_array_2).sum(),
(np.ones((90, 90, 90), dtype=np.int).sum() -
(np.logical_or(test_array_1, test_array_2).sum())))

# subtract
assert_equal(img.logical('sub', test_array_1, test_array_1), False)

test_result = img.logical('sub', test_array_1, test_array_2)
assert_equal(test_result[20:39, 20:39, 20:39], False)

assert_equal(test_result.sum(), (test_array_1.sum() -
np.logical_and(test_array_1,
test_array_2).sum()))

test_result = img.logical('sub', test_array_1, test_array_3)
assert_equal(test_result, test_array_1)


if __name__ == '__main__':
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)
Loading