Finish porting to ctypes. It runs.
authorStefan van der Walt <stefan@sun.ac.za>
Tue Jan 22 19:17:00 2008 +0200 (4 years ago)
changeset 1d82471bc3d86
parent 09d939752c760
child 2933f0df6f1ce
Finish porting to ctypes. It runs.
COPYING.txt
__init__.py
glcom.py
greycomat.c
greycomat.cc
greycomatrix.py
setup.py
test_glcom.py
       1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
       2 +++ b/COPYING.txt	Tue Jan 22 19:17:00 2008 +0200
       3 @@ -0,0 +1,23 @@
       4 +Copyright (c) 2007, Stéfan van der Walt
       5 +
       6 +Permission is hereby granted, free of charge, to any person obtaining
       7 +a copy of this software and associated documentation files (the
       8 +"Software"), to deal in the Software without restriction, including
       9 +without limitation the rights to use, copy, modify, merge, publish,
      10 +distribute, sublicense, and/or sell copies of the Software, and to
      11 +permit persons to whom the Software is furnished to do so, subject to
      12 +the following conditions:
      13 +
      14 +  1. Redistributions of source code must retain the above copyright
      15 +     notice, this list of conditions and the following disclaimers.
      16 +  2. Redistributions in binary form must reproduce the above copyright
      17 +     notice in the documentation and/or other materials provided with
      18 +     the distribution.
      19 +
      20 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      21 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      22 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
      23 +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
      24 +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
      25 +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
      26 +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/__init__.py	Tue Jan 22 19:17:00 2008 +0200
     1.3 @@ -0,0 +1,1 @@
     1.4 +import glcom
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/glcom.py	Tue Jan 22 19:17:00 2008 +0200
     2.3 @@ -0,0 +1,90 @@
     2.4 +import numpy as np
     2.5 +import sys
     2.6 +
     2.7 +try:
     2.8 +    from ctypes import c_int, c_uint8, c_double, c_char, Structure, POINTER
     2.9 +except:
    2.10 +    print "Requires ctypes > 1.0.1"
    2.11 +    sys.exit(-1)
    2.12 +
    2.13 +try:
    2.14 +    _glcom = np.ctypeslib.load_library('libgreycomat_',__file__)
    2.15 +except:
    2.16 +    print \
    2.17 +"""Failed to load libgreycomat_.so.  Compile the library using
    2.18 +
    2.19 +python setup.py build_ext -i
    2.20 +
    2.21 +from the package root directory."""
    2.22 +    sys.exit(-1)
    2.23 +
    2.24 +array_1d_int = np.ctypeslib.ndpointer(dtype=np.intc,ndim=1,
    2.25 +                                      flags='CONTIGUOUS')
    2.26 +array_2d_int = np.ctypeslib.ndpointer(dtype=np.intc,ndim=2,
    2.27 +                                      flags='CONTIGUOUS')
    2.28 +array_4d_int = np.ctypeslib.ndpointer(dtype=np.intc,ndim=4,
    2.29 +                                      flags='CONTIGUOUS')
    2.30 +
    2.31 +# Define API
    2.32 +libglcom_api = {
    2.33 +   'greycomat' : (None,
    2.34 +                  [array_2d_int, c_int, c_int,
    2.35 +                   array_1d_int, c_int,
    2.36 +                   array_1d_int, c_int,
    2.37 +                   c_int,
    2.38 +                   array_4d_int],
    2.39 +                  )
    2.40 +}
    2.41 +
    2.42 +def register_api(lib,api):
    2.43 +    for f, (restype, argtypes) in api.iteritems():
    2.44 +        func = getattr(lib, f)
    2.45 +        func.restype = restype
    2.46 +        func.argtypes = argtypes
    2.47 +
    2.48 +register_api(_glcom,libglcom_api)
    2.49 +
    2.50 +
    2.51 +def glcom(image, distances, angles, levels=255):
    2.52 +    """Calculate the gray-level co-occurrence matrix P of a grey-level image.
    2.53 +
    2.54 +    Parameters
    2.55 +    ----------
    2.56 +        image : (M,N) ndarray of dtype int
    2.57 +            Input image.
    2.58 +        distances : (K,) ndarray
    2.59 +            Histogram distances.
    2.60 +        angles : (L,) ndarray
    2.61 +            Histogram angles.
    2.62 +        levels : int
    2.63 +            The input image should contain integers in [0, levels-1],
    2.64 +            where levels indicate the number of grey-levels counted
    2.65 +            (typically 256 for an 8-bit image).
    2.66 +
    2.67 +    Returns
    2.68 +    -------
    2.69 +        P : 4-dimensional ndarray
    2.70 +           The grey-level co-occurrence histogram. The value
    2.71 +           P[i,j,d,theta] is the number of times that gray-level j
    2.72 +           occurs at a distance d and at an angle theta from
    2.73 +           gray-level i.
    2.74 +
    2.75 +    """
    2.76 +    assert image.ndim == 2
    2.77 +    assert image.min() >= 0
    2.78 +    assert image.max() < levels
    2.79 +    image = image.astype(c_int)
    2.80 +    distances = np.asarray(distances,dtype=c_int)
    2.81 +    angles = np.asarray(angles,dtype=c_int)
    2.82 +    assert distances.ndim == 1
    2.83 +    assert angles.ndim == 1
    2.84 +
    2.85 +    out = np.zeros((levels,levels,len(distances),len(angles)),
    2.86 +                   dtype=c_int)
    2.87 +
    2.88 +    rows,cols = image.shape
    2.89 +    _glcom.greycomat(image,rows,cols,
    2.90 +                     distances,len(distances),
    2.91 +                     angles,len(angles),
    2.92 +                     levels,out)
    2.93 +    return out
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/greycomat.c	Tue Jan 22 19:17:00 2008 +0200
     3.3 @@ -0,0 +1,44 @@
     3.4 +#include <math.h>
     3.5 +
     3.6 +void
     3.7 +greycomat(int* input, int rows, int cols,
     3.8 +          int* distances, int dsize,
     3.9 +          int* angles, int asize,
    3.10 +          int levels, int* output) {
    3.11 +    int r, c, i, j, d_idx, d_val, angle_idx, row, col;
    3.12 +    double angle;
    3.13 +
    3.14 +    /* 4-dimensional histogram
    3.15 +       P = f(i, j, d, theta) where i and j are grey levels
    3.16 +       See Pattern Recognition Engineering (Morton Nadler & Eric P. Smith) */
    3.17 +
    3.18 +    for (r = 0; r < rows; r++) {
    3.19 +	for (c = 0; c < cols; c++) {
    3.20 +	    i = input[r*cols + c];
    3.21 +
    3.22 +	    for (d_idx = 0; d_idx < dsize; d_idx++) {
    3.23 +		d_val = distances[d_idx];
    3.24 +		for (angle_idx = 0; angle_idx < asize; angle_idx++) {
    3.25 +                    angle = angles[angle_idx];
    3.26 +
    3.27 +		    row = r + (int)floor(cos(angle) * d_val + 0.5);
    3.28 +		    col = c - (int)floor(sin(angle) * d_val + 0.5);
    3.29 +
    3.30 +		    if ((row >= 0) && (row < rows) &&
    3.31 +			(col >= 0) && (col < cols)) {
    3.32 +
    3.33 +			j = input[row*cols + col];
    3.34 +
    3.35 +			if (i >= 0 && i < levels && j >= 0 && j < levels) {
    3.36 +                            output[((i*levels + j)*dsize
    3.37 +                                    + d_idx)*asize + angle_idx]++;
    3.38 +			} // else raise a warning
    3.39 +		    }
    3.40 +
    3.41 +		}
    3.42 +	    }
    3.43 +
    3.44 +	}
    3.45 +    }
    3.46 +}
    3.47 +
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/setup.py	Tue Jan 22 19:17:00 2008 +0200
     4.3 @@ -0,0 +1,15 @@
     4.4 +from os.path import join, dirname
     4.5 +from glob import glob
     4.6 +
     4.7 +def configuration(parent_package='', top_path=None,
     4.8 +                  package_name='glcom'):
     4.9 +    from numpy.distutils.misc_util import Configuration
    4.10 +    config = Configuration(package_name,parent_package,top_path)
    4.11 +    config.add_extension('libgreycomat_',
    4.12 +                         sources=join(dirname(__file__),'greycomat.c'),
    4.13 +                         libraries=['m'])
    4.14 +    return config
    4.15 +
    4.16 +if __name__ == '__main__':
    4.17 +    from numpy.distutils.core import setup
    4.18 +    setup(configuration=configuration)
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/test_glcom.py	Tue Jan 22 19:17:00 2008 +0200
     5.3 @@ -0,0 +1,19 @@
     5.4 +import numpy as np
     5.5 +from numpy.testing import *
     5.6 +
     5.7 +import glcom
     5.8 +
     5.9 +class test_shortest_path(NumpyTestCase):
    5.10 +    def test_basic(self):
    5.11 +        A = np.array([[0,0,0,1,2],
    5.12 +                      [1,1,0,1,1],
    5.13 +                      [2,2,1,0,0],
    5.14 +                      [1,1,0,2,0],
    5.15 +                      [0,0,1,0,1]])
    5.16 +
    5.17 +        P = glcom.glcom(A,[1],[0,-np.pi/2.],levels=3)
    5.18 +        print P[:,:,0,0]
    5.19 +        print P[:,:,0,1]
    5.20 +
    5.21 +if __name__ == "__main__":
    5.22 +    NumpyTest().run()
     6.1 --- a/greycomat.cc	Tue Jan 22 18:10:53 2008 +0200
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,67 +0,0 @@
     6.4 -"""Copyright (C) 2004 Stefan van der Walt <stefan@sun.ac.za>
     6.5 -
     6.6 -   Redistribution and use in source and binary forms, with or without
     6.7 -   modification, are permitted provided that the following conditions are
     6.8 -   met:
     6.9 -
    6.10 -   1. Redistributions of source code must retain the above copyright notice,
    6.11 -      this list of conditions and the following disclaimer.
    6.12 -   2. Redistributions in binary form must reproduce the above copyright
    6.13 -      notice, this list of conditions and the following disclaimer in the
    6.14 -      documentation and/or other materials provided with the distribution.
    6.15 -
    6.16 -  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    6.17 -  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    6.18 -  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    6.19 -  ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
    6.20 -  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    6.21 -  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
    6.22 -  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    6.23 -  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
    6.24 -  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    6.25 -  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
    6.26 -  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    6.27 -
    6.28 -"""
    6.29 -
    6.30 -void
    6.31 -graycomat(int* input, int rows, int cols,
    6.32 -          int* distances, int dsize,
    6.33 -          int* angles, int asize,
    6.34 -          int levels, int* output) {
    6.35 -    int r, c, i, j, d_idx, d_val, angle_idx, row, col;
    6.36 -    double angle;
    6.37 -
    6.38 -    /* 4-dimensional histogram
    6.39 -       P = f(i, j, d, theta) where i and j are gray levels
    6.40 -       See Pattern Recognition Engineering (Morton Nadler & Eric P. Smith) */
    6.41 -
    6.42 -    for (int r = 0; r < rows; r++) {
    6.43 -	for (int c = 0; c < columns; c++) {
    6.44 -	    i = input[r*columns + c]l
    6.45 -
    6.46 -	    for (d_idx = 0; d_idx < dsize; d_idx++) {
    6.47 -		d_val = distances(d_idx);
    6.48 -		for (angle_idx = 0; angle_idx < asize; angle_idx++) {
    6.49 -                    angle = angles(th_idx);
    6.50 -
    6.51 -		    row = r + (int)floor(cos(angle) * d_val + 0.5);
    6.52 -		    col = c - (int)floor(sin(angle) * d_val + 0.5);
    6.53 -
    6.54 -		    if ((row >= 0) && (row < rows) &&
    6.55 -			(col >= 0) && (col < columns)) {
    6.56 -
    6.57 -			int j = input[row*columns + col];
    6.58 -
    6.59 -			if (i >= 0 && i < L && j >= 0 && j < L) {
    6.60 -                            output[i][j][d_idx][th_idx]++;
    6.61 -			} // else raise a warning
    6.62 -		    }
    6.63 -
    6.64 -		}
    6.65 -	    }
    6.66 -
    6.67 -	}
    6.68 -    }
    6.69 -}
    6.70 -
     7.1 --- a/greycomatrix.py	Tue Jan 22 18:10:53 2008 +0200
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,66 +0,0 @@
     7.4 -"""Copyright (C) 2004 Stefan van der Walt <stefan@sun.ac.za>
     7.5 -
     7.6 -   Redistribution and use in source and binary forms, with or without
     7.7 -   modification, are permitted provided that the following conditions are
     7.8 -   met:
     7.9 -
    7.10 -   1. Redistributions of source code must retain the above copyright notice,
    7.11 -      this list of conditions and the following disclaimer.
    7.12 -   2. Redistributions in binary form must reproduce the above copyright
    7.13 -      notice, this list of conditions and the following disclaimer in the
    7.14 -      documentation and/or other materials provided with the distribution.
    7.15 -
    7.16 -  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    7.17 -  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    7.18 -  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    7.19 -  ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
    7.20 -  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    7.21 -  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
    7.22 -  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    7.23 -  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
    7.24 -  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    7.25 -  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
    7.26 -  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    7.27 -
    7.28 -"""
    7.29 -
    7.30 -import numpy as np
    7.31 -
    7.32 -def graycomatrix(image, distances, angles, levels=255):
    7.33 -    """Calculate the gray-level co-occurrence matrix P of a grey-level image.
    7.34 -
    7.35 -    Parameters
    7.36 -    ----------
    7.37 -        image : (M,N) ndarray of dtype int
    7.38 -            Input image.
    7.39 -        distances : (K,) ndarray
    7.40 -            Histogram distances.
    7.41 -        angles : (L,) ndarray
    7.42 -            Histogram angles.
    7.43 -        levels : int
    7.44 -            The input image should contain integers in [0, levels-1],
    7.45 -            where levels indicate the number of grey-levels counted
    7.46 -            (typically 256 for an 8-bit image).
    7.47 -
    7.48 -    Returns
    7.49 -    -------
    7.50 -        P : 4-dimensional ndarray
    7.51 -           The grey-level co-occurrence histogram. The value
    7.52 -           P[i,j,d,theta] is the number of times that gray-level j
    7.53 -           occurs at a distance d and at an angle theta from
    7.54 -           gray-level i.
    7.55 -
    7.56 -    """
    7.57 -    assert image.ndim == 2
    7.58 -    assert image.min >= 0
    7.59 -    assert image.max < levels
    7.60 -    image = image.astype(np.c_int)
    7.61 -    out = zeros((levels,levels,len(distances),len(angles)),
    7.62 -                dtype=np.c_int)
    7.63 -
    7.64 -    rows,cols = image.shape
    7.65 -    _graycomat(image,rows,cols,
    7.66 -               distances,len(distances),
    7.67 -               angles,len(angles),
    7.68 -               levels,out)
    7.69 -    return out