Use typed memoryviews in filter package

This commit is contained in:
Johannes Schönberger
2013-08-17 22:47:03 +02:00
parent 3172f508d6
commit f76ba9dff3
2 changed files with 32 additions and 49 deletions
+7 -14
View File
@@ -731,13 +731,8 @@ cdef int c_median_filter(Py_ssize_t rows,
return 0
def median_filter(cnp.ndarray[dtype=cnp.uint8_t, ndim=2,
negative_indices=False, mode='c'] data,
cnp.ndarray[dtype=cnp.uint8_t, ndim=2,
negative_indices=False, mode='c'] mask,
cnp.ndarray[dtype=cnp.uint8_t, ndim=2,
negative_indices=False, mode='c'] output,
int radius,
def median_filter(cnp.uint8_t[:, ::1] data, cnp.uint8_t[:, ::1] mask,
cnp.uint8_t[:, ::1] output, int radius,
cnp.int32_t percent):
"""Median filter with octagon shape and masking.
@@ -773,12 +768,10 @@ def median_filter(cnp.ndarray[dtype=cnp.uint8_t, ndim=2,
raise ValueError('Data shape (%d, %d) is not output shape (%d, %d)' %
(data.shape[0], data.shape[1],
output.shape[0], output.shape[1]))
if c_median_filter(<cnp.int32_t>data.shape[0],
<cnp.int32_t>data.shape[1],
<cnp.int32_t>data.strides[0],
<cnp.int32_t>data.strides[1],
if c_median_filter(data.shape[0], data.shape[1],
data.strides[0], data.strides[1],
radius, percent,
<cnp.uint8_t*>data.data,
<cnp.uint8_t*>mask.data,
<cnp.uint8_t*>output.data):
&data[0, 0],
&mask[0, 0],
&output[0, 0]):
raise MemoryError('Failed to allocate scratchpad memory')
+25 -35
View File
@@ -113,11 +113,8 @@ def denoise_bilateral(image, Py_ssize_t win_size=5, sigma_range=None,
double max_value
cnp.ndarray[dtype=cnp.double_t, ndim=3, mode='c'] cimage
cnp.ndarray[dtype=cnp.double_t, ndim=3, mode='c'] out
double* image_data
double* out_data
double[:, :, ::1] cimage
double[:, :, ::1] out
double* color_lut
double* range_lut
@@ -143,8 +140,6 @@ def denoise_bilateral(image, Py_ssize_t win_size=5, sigma_range=None,
cimage = np.ascontiguousarray(image)
out = np.zeros((rows, cols, dims), dtype=np.double)
image_data = <double*>cimage.data
out_data = <double*>out.data
color_lut = _compute_color_lut(bins, csigma_range, max_value)
range_lut = _compute_range_lut(win_size, sigma_spatial)
dist_scale = bins / dims / max_value
@@ -159,11 +154,10 @@ def denoise_bilateral(image, Py_ssize_t win_size=5, sigma_range=None,
for r in range(rows):
for c in range(cols):
pixel_addr = r * cols * dims + c * dims
total_weight = 0
for d in range(dims):
total_values[d] = 0
centres[d] = image_data[pixel_addr + d]
centres[d] = cimage[r, c, d]
for wr in range(-window_ext, window_ext + 1):
rr = wr + r
kr = wr + window_ext
@@ -175,7 +169,7 @@ def denoise_bilateral(image, Py_ssize_t win_size=5, sigma_range=None,
# distance between centre stack and current position
dist = 0
for d in range(dims):
value = get_pixel3d(image_data, rows, cols, dims,
value = get_pixel3d(&cimage[0, 0, 0], rows, cols, dims,
rr, cc, d, cmode, cval)
values[d] = value
dist += (centres[d] - value)**2
@@ -189,7 +183,7 @@ def denoise_bilateral(image, Py_ssize_t win_size=5, sigma_range=None,
total_values[d] += values[d] * weight
total_weight += weight
for d in range(dims):
out_data[pixel_addr + d] = total_values[d] / total_weight
out[r, c, d] = total_values[d] / total_weight
free(color_lut)
free(range_lut)
@@ -197,11 +191,11 @@ def denoise_bilateral(image, Py_ssize_t win_size=5, sigma_range=None,
free(centres)
free(total_values)
return np.squeeze(out)
return np.squeeze(np.asarray(out))
def denoise_tv_bregman(image, double weight, int max_iter=100, double eps=1e-3,
isotropic=True):
char isotropic=True):
"""Perform total-variation denoising using split-Bregman optimization.
Total-variation denoising (also know as total-variation regularization)
@@ -258,21 +252,17 @@ def denoise_tv_bregman(image, double weight, int max_iter=100, double eps=1e-3,
Py_ssize_t total = rows * cols * dims
shape_ext = (rows2, cols2, dims)
shape_ext = (rows2, cols2, dims)
u = np.zeros(shape_ext, dtype=np.double)
cnp.ndarray[dtype=cnp.double_t, ndim=3, mode='c'] cimage = \
np.ascontiguousarray(image)
cnp.ndarray[dtype=cnp.double_t, ndim=3, mode='c'] u = \
np.zeros(shape_ext, dtype=np.double)
cdef:
double[:, :, ::1] cimage = np.ascontiguousarray(image)
double[:, :, ::1] cu = u
cnp.ndarray[dtype=cnp.double_t, ndim=3, mode='c'] dx = \
np.zeros(shape_ext, dtype=np.double)
cnp.ndarray[dtype=cnp.double_t, ndim=3, mode='c'] dy = \
np.zeros(shape_ext, dtype=np.double)
cnp.ndarray[dtype=cnp.double_t, ndim=3, mode='c'] bx = \
np.zeros(shape_ext, dtype=np.double)
cnp.ndarray[dtype=cnp.double_t, ndim=3, mode='c'] by = \
np.zeros(shape_ext, dtype=np.double)
double[:, :, ::1] dx = np.zeros(shape_ext, dtype=np.double)
double[:, :, ::1] dy = np.zeros(shape_ext, dtype=np.double)
double[:, :, ::1] bx = np.zeros(shape_ext, dtype=np.double)
double[:, :, ::1] by = np.zeros(shape_ext, dtype=np.double)
double ux, uy, uprev, unew, bxx, byy, dxx, dyy, s
int i = 0
@@ -296,19 +286,19 @@ def denoise_tv_bregman(image, double weight, int max_iter=100, double eps=1e-3,
for r in range(1, rows + 1):
for c in range(1, cols + 1):
uprev = u[r, c, k]
uprev = cu[r, c, k]
# forward derivatives
ux = u[r, c + 1, k] - uprev
uy = u[r + 1, c, k] - uprev
ux = cu[r, c + 1, k] - uprev
uy = cu[r + 1, c, k] - uprev
# Gauss-Seidel method
unew = (
lam * (
+ u[r + 1, c, k]
+ u[r - 1, c, k]
+ u[r, c + 1, k]
+ u[r, c - 1, k]
+ cu[r + 1, c, k]
+ cu[r - 1, c, k]
+ cu[r, c + 1, k]
+ cu[r, c - 1, k]
+ dx[r, c - 1, k]
- dx[r, c, k]
@@ -321,7 +311,7 @@ def denoise_tv_bregman(image, double weight, int max_iter=100, double eps=1e-3,
+ by[r, c, k]
) + weight * cimage[r - 1, c - 1, k]
) / norm
u[r, c, k] = unew
cu[r, c, k] = unew
# update root mean square error
rmse += (unew - uprev)**2
@@ -360,4 +350,4 @@ def denoise_tv_bregman(image, double weight, int max_iter=100, double eps=1e-3,
rmse = sqrt(rmse / total)
i += 1
return np.squeeze(u[1:-1, 1:-1])
return np.squeeze(np.asarray(u[1:-1, 1:-1]))