mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-19 11:27:45 +08:00
Merge branch 'spath'
Conflicts: .gitignore scikits/image/opencv/setup.py
This commit is contained in:
+1
-1
@@ -6,10 +6,10 @@
|
||||
*.bak
|
||||
*.c
|
||||
.gitignore
|
||||
*.new
|
||||
doc/source/api
|
||||
doc/build
|
||||
source/api
|
||||
scikits/image/opencv/*.new
|
||||
build
|
||||
dist
|
||||
scikits/image/version.py
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
import os
|
||||
import shutil
|
||||
import hashlib
|
||||
|
||||
def cython(pyx_files, working_path=''):
|
||||
"""Use Cython to convert the given files to C.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
pyx_files : list of str
|
||||
The input .pyx files.
|
||||
|
||||
"""
|
||||
try:
|
||||
import Cython
|
||||
except ImportError:
|
||||
# If cython is not found, we do nothing -- the build will make use of
|
||||
# the distributed .c files
|
||||
pass
|
||||
else:
|
||||
for pyxfile in [os.path.join(working_path, f) for f in pyx_files]:
|
||||
# make a backup of the good c files
|
||||
c_file = pyxfile[:-4] + 'c'
|
||||
c_file_new = c_file + '.new'
|
||||
|
||||
# run cython compiler
|
||||
cmd = 'cython -o %s %s' % (c_file_new, pyxfile)
|
||||
print cmd
|
||||
status = os.system(cmd)
|
||||
|
||||
# if the resulting file is small, cython compilation failed
|
||||
size = os.path.getsize(c_file_new)
|
||||
if status != 0 or (size < 100):
|
||||
print "Cython compilation of %s failed. Falling back " \
|
||||
"on pre-generated file." % os.path.basename(pyxfile)
|
||||
continue
|
||||
|
||||
# if the generated .c file differs from the one provided,
|
||||
# use that one instead
|
||||
if not same_cython(c_file_new, c_file):
|
||||
shutil.copy(c_file_new, c_file)
|
||||
|
||||
def same_cython(f0, f1):
|
||||
'''Compare two Cython generated C-files, based on their md5-sum.
|
||||
|
||||
Returns True if the files are identical, False if not. The first
|
||||
lines are skipped, due to the timestamp printed there.
|
||||
|
||||
'''
|
||||
def md5sum(f):
|
||||
m = hashlib.new('md5')
|
||||
while True:
|
||||
d = f.read(8096)
|
||||
if not d:
|
||||
break
|
||||
m.update(d)
|
||||
return m.hexdigest()
|
||||
|
||||
if not (os.path.isfile(f0) and os.path.isfile(f1)):
|
||||
return False
|
||||
|
||||
f0 = file(f0)
|
||||
f0.readline()
|
||||
|
||||
f1 = file(f1)
|
||||
f1.readline()
|
||||
|
||||
return md5sum(f0) == md5sum(f1)
|
||||
@@ -0,0 +1 @@
|
||||
from spath import shortest_path
|
||||
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from scikits.image._build import cython
|
||||
|
||||
import os.path
|
||||
|
||||
base_path = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
def configuration(parent_package='', top_path=None):
|
||||
from numpy.distutils.misc_util import Configuration, get_numpy_include_dirs
|
||||
|
||||
config = Configuration('analysis', parent_package, top_path)
|
||||
config.add_data_dir('tests')
|
||||
|
||||
# This function tries to create C files from the given .pyx files. If
|
||||
# it fails, we build the checked-in .c files.
|
||||
cython(['spath.pyx'], working_path=base_path)
|
||||
|
||||
config.add_extension('spath', sources=['spath.c'],
|
||||
include_dirs=[get_numpy_include_dirs()])
|
||||
|
||||
return config
|
||||
|
||||
if __name__ == '__main__':
|
||||
from numpy.distutils.core import setup
|
||||
setup(maintainer = 'scikits.image Developers',
|
||||
maintainer_email = 'scikits-image@googlegroups.com',
|
||||
description = 'Image Analysis Tools',
|
||||
url = 'http://stefanv.github.com/scikits.image/',
|
||||
license = 'Modified BSD',
|
||||
**(configuration(top_path='').todict())
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,68 @@
|
||||
# -*- python -*-
|
||||
|
||||
import numpy as np
|
||||
cimport numpy as np
|
||||
|
||||
cdef extern from "math.h":
|
||||
double fabs(double f)
|
||||
|
||||
cpdef shortest_path(np.ndarray arr):
|
||||
"""Find the shortest left-to-right path through an array.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
arr : (M,N) ndarray of float64
|
||||
|
||||
"""
|
||||
if arr.ndim != 2:
|
||||
raise ValueError("Expected 2-D array as input")
|
||||
|
||||
cdef np.ndarray[np.double_t, ndim=2] data = \
|
||||
np.ascontiguousarray(arr, dtype=np.double)
|
||||
|
||||
cdef int M = arr.shape[0]
|
||||
cdef int N = arr.shape[1]
|
||||
|
||||
cdef np.ndarray[np.int_t, ndim=2] node = \
|
||||
np.empty((M, N), dtype=int)
|
||||
|
||||
cdef np.ndarray[np.double_t, ndim=2] cost = \
|
||||
np.empty((M, N), dtype=np.double)
|
||||
|
||||
cdef np.ndarray[np.int_t] out = np.empty((N,), dtype=int)
|
||||
|
||||
cdef int c, r, rb, r_min_node
|
||||
cdef int r_bracket_min = 0, r_bracket_max = 0
|
||||
cdef double delta0 = 0, delta1 = 0
|
||||
|
||||
cost[:, 0] = 0
|
||||
|
||||
for c in range(1, N):
|
||||
for r in range(M):
|
||||
r_bracket_min = r - 1
|
||||
r_bracket_max = r + 1
|
||||
|
||||
if r_bracket_min < 0:
|
||||
r_bracket_min = 0
|
||||
if r_bracket_max > M - 1:
|
||||
r_bracket_max = M - 1
|
||||
|
||||
node[r, c] = r_bracket_min
|
||||
for rb in range(r_bracket_min + 1, r_bracket_max + 1):
|
||||
delta0 = fabs(data[rb, c] - data[rb, c - 1])
|
||||
delta1 = fabs(data[rb, c] - data[node[r, c], c - 1])
|
||||
if delta0 < delta1:
|
||||
node[r, c] = rb
|
||||
|
||||
cost[r, c] = cost[node[r, c], c - 1] + \
|
||||
fabs(data[r, c] - data[node[r, c], c - 1])
|
||||
|
||||
# Find minimum cost path
|
||||
r_min_node = cost[:,-1].argmin()
|
||||
|
||||
# Backtrack
|
||||
out[N - 1] = r_min_node
|
||||
for c in range(N - 1, 0, -1):
|
||||
out[c - 1] = node[out[c], c]
|
||||
|
||||
return out, cost[r_min_node, N - 1]
|
||||
@@ -0,0 +1,17 @@
|
||||
import numpy as np
|
||||
from numpy.testing import *
|
||||
|
||||
from scikits.image.analysis import shortest_path
|
||||
|
||||
class TestShortestPath:
|
||||
def test_basic(self):
|
||||
x = np.array([[1, 1, 3],
|
||||
[0, 2, 0],
|
||||
[4, 3, 1]])
|
||||
y = np.empty((3,))
|
||||
path, cost = shortest_path(x)
|
||||
assert_array_equal(path, [0, 0, 1])
|
||||
assert_equal(cost, 1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_module_suite()
|
||||
@@ -1,35 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import hashlib
|
||||
from scikits.image._build import cython
|
||||
|
||||
base_path = os.path.dirname(__file__)
|
||||
|
||||
def same_cython(f0, f1):
|
||||
'''Compare two Cython generated C-files, based on their md5-sum.
|
||||
|
||||
Returns True if the files are identical, False if not. The first
|
||||
lines are skipped, due to the timestamp printed there.
|
||||
|
||||
'''
|
||||
def md5sum(f):
|
||||
m = hashlib.new('md5')
|
||||
while True:
|
||||
d = f.read(8096)
|
||||
if not d:
|
||||
break
|
||||
m.update(d)
|
||||
return m.hexdigest()
|
||||
|
||||
f0 = file(f0)
|
||||
f0.readline()
|
||||
|
||||
f1 = file(f1)
|
||||
f1.readline()
|
||||
|
||||
return md5sum(f0) == md5sum(f1)
|
||||
import os.path
|
||||
|
||||
base_path = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
def configuration(parent_package='', top_path=None):
|
||||
from numpy.distutils.misc_util import Configuration, get_numpy_include_dirs
|
||||
@@ -38,40 +13,14 @@ def configuration(parent_package='', top_path=None):
|
||||
|
||||
config.add_data_dir('tests')
|
||||
|
||||
# since distutils/cython has problems, we'll check to see if cython is
|
||||
# installed and use that to rebuild the .c files, if not, we'll just build
|
||||
# directly from the included .c files
|
||||
|
||||
cython_files = ['opencv_backend.pyx', 'opencv_cv.pyx']
|
||||
|
||||
try:
|
||||
import Cython
|
||||
for pyxfile in [os.path.join(base_path, f) for f in cython_files]:
|
||||
# make a backup of the good c files
|
||||
c_file = pyxfile[:-4] + 'c'
|
||||
c_file_new = c_file + '.new'
|
||||
|
||||
# run cython compiler
|
||||
os.system('cython -o %s %s' % (c_file_new, pyxfile))
|
||||
|
||||
# if the resulting file is small, cython compilation failed
|
||||
size = os.path.getsize(c_file_new)
|
||||
if size < 100:
|
||||
print "Cython compilation of %s failed. Using " \
|
||||
"pre-generated file." % os.path.basename(pyxfile)
|
||||
continue
|
||||
|
||||
# if the generated .c file differs from the one provided,
|
||||
# use that one instead
|
||||
if not same_cython(c_file_new, c_file):
|
||||
shutil.copy(c_file_new, c_file)
|
||||
|
||||
except ImportError:
|
||||
# if cython is not found, we just build from the included .c files
|
||||
pass
|
||||
# This function tries to create C files from the given .pyx files. If
|
||||
# it fails, we build the checked-in .c files.
|
||||
cython(cython_files, working_path=base_path)
|
||||
|
||||
for pyxfile in cython_files:
|
||||
c_file = pyxfile[:-4] + 'c'
|
||||
c_file = pyxfile[:-4] + '.c'
|
||||
config.add_extension(pyxfile[:-4],
|
||||
sources=[c_file],
|
||||
include_dirs=[get_numpy_include_dirs()])
|
||||
|
||||
Reference in New Issue
Block a user