Finish porting to ctypes. It runs.
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