rm CondaPkg environment

This commit is contained in:
ton
2023-04-06 13:53:47 +07:00
parent 0a57ed7884
commit c43d949309
3329 changed files with 5725 additions and 447022 deletions

View File

@@ -1,62 +0,0 @@
import pytest
import numpy as np
from skimage.feature import multiscale_basic_features
@pytest.mark.parametrize('edges', (False, True))
@pytest.mark.parametrize('texture', (False, True))
def test_multiscale_basic_features_gray(edges, texture):
img = np.zeros((20, 20))
img[:10] = 1
img += 0.05 * np.random.randn(*img.shape)
features = multiscale_basic_features(img, edges=edges, texture=texture)
n_sigmas = 6
intensity = True
assert features.shape[-1] == (
n_sigmas * (int(intensity) + int(edges) + 2 * int(texture))
)
assert features.shape[:-1] == img.shape[:]
@pytest.mark.parametrize('edges', (False, True))
@pytest.mark.parametrize('texture', (False, True))
def test_multiscale_basic_features_rgb(edges, texture):
img = np.zeros((20, 20, 3))
img[:10] = 1
img += 0.05 * np.random.randn(*img.shape)
features = multiscale_basic_features(img, edges=edges, texture=texture,
channel_axis=-1)
n_sigmas = 6
intensity = True
assert features.shape[-1] == (
3 * n_sigmas * (int(intensity) + int(edges) + 2 * int(texture))
)
assert features.shape[:-1] == img.shape[:-1]
@pytest.mark.parametrize('channel_axis', [0, 1, 2, -1, -2])
def test_multiscale_basic_features_channel_axis(channel_axis):
num_channels = 5
shape_spatial = (10, 10)
ndim = len(shape_spatial)
shape = tuple(
np.insert(shape_spatial, channel_axis % (ndim + 1), num_channels)
)
img = np.zeros(shape)
img[:10] = 1
img += 0.05 * np.random.randn(*img.shape)
n_sigmas = 2
# features for all channels are concatenated along the last axis
features = multiscale_basic_features(img, sigma_min=1, sigma_max=2,
channel_axis=channel_axis)
assert features.shape[-1] == 5 * n_sigmas * 4
assert features.shape[:-1] == np.moveaxis(img, channel_axis, -1).shape[:-1]
# Consider channel_axis as spatial dimension
features = multiscale_basic_features(img, sigma_min=1, sigma_max=2)
assert features.shape[-1] == n_sigmas * 5
assert features.shape[:-1] == img.shape

View File

@@ -1,583 +0,0 @@
import math
import numpy as np
import pytest
from numpy.testing import assert_almost_equal
from skimage import feature
from skimage.draw import disk
from skimage.draw.draw3d import ellipsoid
from skimage.feature import blob_dog, blob_doh, blob_log
from skimage.feature.blob import _blob_overlap
@pytest.mark.parametrize(
'dtype', [np.uint8, np.float16, np.float32, np.float64]
)
@pytest.mark.parametrize('threshold_type', ['absolute', 'relative'])
def test_blob_dog(dtype, threshold_type):
r2 = math.sqrt(2)
img = np.ones((512, 512), dtype=dtype)
xs, ys = disk((400, 130), 5)
img[xs, ys] = 255
xs, ys = disk((100, 300), 25)
img[xs, ys] = 255
xs, ys = disk((200, 350), 45)
img[xs, ys] = 255
if threshold_type == 'absolute':
threshold = 2.0
if img.dtype.kind != 'f':
# account for internal scaling to [0, 1] by img_as_float
threshold /= img.ptp()
threshold_rel = None
elif threshold_type == 'relative':
threshold = None
threshold_rel = 0.5
blobs = blob_dog(
img,
min_sigma=4,
max_sigma=50,
threshold=threshold,
threshold_rel=threshold_rel,
)
def radius(x):
return r2 * x[2]
s = sorted(blobs, key=radius)
thresh = 5
ratio_thresh = 0.25
b = s[0]
assert abs(b[0] - 400) <= thresh
assert abs(b[1] - 130) <= thresh
assert abs(radius(b) - 5) <= ratio_thresh * 5
b = s[1]
assert abs(b[0] - 100) <= thresh
assert abs(b[1] - 300) <= thresh
assert abs(radius(b) - 25) <= ratio_thresh * 25
b = s[2]
assert abs(b[0] - 200) <= thresh
assert abs(b[1] - 350) <= thresh
assert abs(radius(b) - 45) <= ratio_thresh * 45
# Testing no peaks
img_empty = np.zeros((100, 100), dtype=dtype)
assert blob_dog(img_empty).size == 0
@pytest.mark.parametrize(
'dtype', [np.uint8, np.float16, np.float32, np.float64]
)
@pytest.mark.parametrize('threshold_type', ['absolute', 'relative'])
def test_blob_dog_3d(dtype, threshold_type):
# Testing 3D
r = 10
pad = 10
im3 = ellipsoid(r, r, r)
im3 = np.pad(im3, pad, mode='constant')
if threshold_type == 'absolute':
threshold = 0.001
threshold_rel = 0
elif threshold_type == 'relative':
threshold = 0
threshold_rel = 0.5
blobs = blob_dog(
im3,
min_sigma=3,
max_sigma=10,
sigma_ratio=1.2,
threshold=threshold,
threshold_rel=threshold_rel,
)
b = blobs[0]
assert b.shape == (4,)
assert b[0] == r + pad + 1
assert b[1] == r + pad + 1
assert b[2] == r + pad + 1
assert abs(math.sqrt(3) * b[3] - r) < 1.1
@pytest.mark.parametrize(
'dtype', [np.uint8, np.float16, np.float32, np.float64]
)
@pytest.mark.parametrize('threshold_type', ['absolute', 'relative'])
def test_blob_dog_3d_anisotropic(dtype, threshold_type):
# Testing 3D anisotropic
r = 10
pad = 10
im3 = ellipsoid(r / 2, r, r)
im3 = np.pad(im3, pad, mode='constant')
if threshold_type == 'absolute':
threshold = 0.001
threshold_rel = None
elif threshold_type == 'relative':
threshold = None
threshold_rel = 0.5
blobs = blob_dog(
im3.astype(dtype, copy=False),
min_sigma=[1.5, 3, 3],
max_sigma=[5, 10, 10],
sigma_ratio=1.2,
threshold=threshold,
threshold_rel=threshold_rel,
)
b = blobs[0]
assert b.shape == (6,)
assert b[0] == r / 2 + pad + 1
assert b[1] == r + pad + 1
assert b[2] == r + pad + 1
assert abs(math.sqrt(3) * b[3] - r / 2) < 1.1
assert abs(math.sqrt(3) * b[4] - r) < 1.1
assert abs(math.sqrt(3) * b[5] - r) < 1.1
@pytest.mark.parametrize("disc_center", [(5, 5), (5, 20)])
@pytest.mark.parametrize("exclude_border", [6, (6, 6), (4, 15)])
def test_blob_dog_exclude_border(disc_center, exclude_border):
# Testing exclude border
# image where blob is disc_center px from borders, radius 5
img = np.ones((512, 512))
xs, ys = disk(disc_center, 5)
img[xs, ys] = 255
blobs = blob_dog(
img,
min_sigma=1.5,
max_sigma=5,
sigma_ratio=1.2,
)
assert blobs.shape[0] == 1, "one blob should have been detected"
b = blobs[0]
assert b[0] == disc_center[0], f"blob should be {disc_center[0]} px from x border"
assert b[1] == disc_center[1], f"blob should be {disc_center[1]} px from y border"
blobs = blob_dog(
img,
min_sigma=1.5,
max_sigma=5,
sigma_ratio=1.2,
exclude_border=exclude_border,
)
if disc_center == (5, 20) and exclude_border == (4, 15):
assert blobs.shape[0] == 1, "one blob should have been detected"
b = blobs[0]
assert b[0] == disc_center[0], f"blob should be {disc_center[0]} px from x border"
assert b[1] == disc_center[1], f"blob should be {disc_center[1]} px from y border"
else:
msg = "zero blobs should be detected, as only blob is 5 px from border"
assert blobs.shape[0] == 0, msg
@pytest.mark.parametrize('anisotropic', [False, True])
@pytest.mark.parametrize('ndim', [1, 2, 3, 4])
@pytest.mark.parametrize('function_name', ['blob_dog', 'blob_log'])
def test_nd_blob_no_peaks_shape(function_name, ndim, anisotropic):
# uniform image so no blobs will be found
z = np.zeros((16,) * ndim, dtype=np.float32)
if anisotropic:
max_sigma = 8 + np.arange(ndim)
else:
max_sigma = 8
blob_func = getattr(feature, function_name)
blobs = blob_func(z, max_sigma=max_sigma)
# z.ndim + (z.ndim sigmas if anisotropic, only one sigma otherwise)
expected_shape = 2 * z.ndim if anisotropic else z.ndim + 1
assert blobs.shape == (0, expected_shape)
@pytest.mark.parametrize(
'dtype', [np.uint8, np.float16, np.float32, np.float64]
)
@pytest.mark.parametrize('threshold_type', ['absolute', 'relative'])
def test_blob_log(dtype, threshold_type):
r2 = math.sqrt(2)
img = np.ones((256, 256), dtype=dtype)
xs, ys = disk((200, 65), 5)
img[xs, ys] = 255
xs, ys = disk((80, 25), 15)
img[xs, ys] = 255
xs, ys = disk((50, 150), 25)
img[xs, ys] = 255
xs, ys = disk((100, 175), 30)
img[xs, ys] = 255
if threshold_type == 'absolute':
threshold = 1
if img.dtype.kind != 'f':
# account for internal scaling to [0, 1] by img_as_float
threshold /= img.ptp()
threshold_rel = None
elif threshold_type == 'relative':
threshold = None
threshold_rel = 0.5
blobs = blob_log(img, min_sigma=5, max_sigma=20, threshold=threshold,
threshold_rel=threshold_rel)
def radius(x):
return r2 * x[2]
s = sorted(blobs, key=radius)
thresh = 3
b = s[0]
assert abs(b[0] - 200) <= thresh
assert abs(b[1] - 65) <= thresh
assert abs(radius(b) - 5) <= thresh
b = s[1]
assert abs(b[0] - 80) <= thresh
assert abs(b[1] - 25) <= thresh
assert abs(radius(b) - 15) <= thresh
b = s[2]
assert abs(b[0] - 50) <= thresh
assert abs(b[1] - 150) <= thresh
assert abs(radius(b) - 25) <= thresh
b = s[3]
assert abs(b[0] - 100) <= thresh
assert abs(b[1] - 175) <= thresh
assert abs(radius(b) - 30) <= thresh
# Testing log scale
blobs = blob_log(
img,
min_sigma=5,
max_sigma=20,
threshold=threshold,
threshold_rel=threshold_rel,
log_scale=True)
b = s[0]
assert abs(b[0] - 200) <= thresh
assert abs(b[1] - 65) <= thresh
assert abs(radius(b) - 5) <= thresh
b = s[1]
assert abs(b[0] - 80) <= thresh
assert abs(b[1] - 25) <= thresh
assert abs(radius(b) - 15) <= thresh
b = s[2]
assert abs(b[0] - 50) <= thresh
assert abs(b[1] - 150) <= thresh
assert abs(radius(b) - 25) <= thresh
b = s[3]
assert abs(b[0] - 100) <= thresh
assert abs(b[1] - 175) <= thresh
assert abs(radius(b) - 30) <= thresh
# Testing no peaks
img_empty = np.zeros((100, 100))
assert blob_log(img_empty).size == 0
def test_blob_log_no_warnings():
img = np.ones((11, 11))
xs, ys = disk((5, 5), 2)
img[xs, ys] = 255
xs, ys = disk((7, 6), 2)
img[xs, ys] = 255
blob_log(img, max_sigma=20, num_sigma=10, threshold=.1)
def test_blob_log_3d():
# Testing 3D
r = 6
pad = 10
im3 = ellipsoid(r, r, r)
im3 = np.pad(im3, pad, mode='constant')
blobs = blob_log(im3, min_sigma=3, max_sigma=10)
b = blobs[0]
assert b.shape == (4,)
assert b[0] == r + pad + 1
assert b[1] == r + pad + 1
assert b[2] == r + pad + 1
assert abs(math.sqrt(3) * b[3] - r) < 1
def test_blob_log_3d_anisotropic():
# Testing 3D anisotropic
r = 6
pad = 10
im3 = ellipsoid(r / 2, r, r)
im3 = np.pad(im3, pad, mode='constant')
blobs = blob_log(
im3,
min_sigma=[1, 2, 2],
max_sigma=[5, 10, 10],
)
b = blobs[0]
assert b.shape == (6,)
assert b[0] == r / 2 + pad + 1
assert b[1] == r + pad + 1
assert b[2] == r + pad + 1
assert abs(math.sqrt(3) * b[3] - r / 2) < 1
assert abs(math.sqrt(3) * b[4] - r) < 1
assert abs(math.sqrt(3) * b[5] - r) < 1
@pytest.mark.parametrize("disc_center", [(5, 5), (5, 20)])
@pytest.mark.parametrize("exclude_border", [6, (6, 6), (4, 15)])
def test_blob_log_exclude_border(disc_center, exclude_border):
# image where blob is disc_center px from borders, radius 5
img = np.ones((512, 512))
xs, ys = disk(disc_center, 5)
img[xs, ys] = 255
blobs = blob_log(
img,
min_sigma=1.5,
max_sigma=5,
)
assert blobs.shape[0] == 1
b = blobs[0]
assert b[0] == disc_center[0], f"blob should be {disc_center[0]} px from x border"
assert b[1] == disc_center[1], f"blob should be {disc_center[1]} px from y border"
blobs = blob_log(
img,
min_sigma=1.5,
max_sigma=5,
exclude_border=exclude_border,
)
if disc_center == (5, 20) and exclude_border == (4, 15):
assert blobs.shape[0] == 1, "one blob should have been detected"
b = blobs[0]
assert b[0] == disc_center[0], f"blob should be {disc_center[0]} px from x border"
assert b[1] == disc_center[1], f"blob should be {disc_center[1]} px from y border"
else:
msg = "zero blobs should be detected, as only blob is 5 px from border"
assert blobs.shape[0] == 0, msg
@pytest.mark.parametrize("dtype", [np.uint8, np.float16, np.float32])
@pytest.mark.parametrize('threshold_type', ['absolute', 'relative'])
def test_blob_doh(dtype, threshold_type):
img = np.ones((512, 512), dtype=dtype)
xs, ys = disk((400, 130), 20)
img[xs, ys] = 255
xs, ys = disk((460, 50), 30)
img[xs, ys] = 255
xs, ys = disk((100, 300), 40)
img[xs, ys] = 255
xs, ys = disk((200, 350), 50)
img[xs, ys] = 255
if threshold_type == 'absolute':
# Note: have to either scale up threshold or rescale the image to the
# range [0, 1] internally.
threshold = 0.05
if img.dtype.kind == 'f':
# account for lack of internal scaling to [0, 1] by img_as_float
ptp = img.ptp()
threshold *= ptp ** 2
threshold_rel = None
elif threshold_type == 'relative':
threshold = None
threshold_rel = 0.5
blobs = blob_doh(
img,
min_sigma=1,
max_sigma=60,
num_sigma=10,
threshold=threshold,
threshold_rel=threshold_rel)
def radius(x):
return x[2]
s = sorted(blobs, key=radius)
thresh = 4
b = s[0]
assert abs(b[0] - 400) <= thresh
assert abs(b[1] - 130) <= thresh
assert abs(radius(b) - 20) <= thresh
b = s[1]
assert abs(b[0] - 460) <= thresh
assert abs(b[1] - 50) <= thresh
assert abs(radius(b) - 30) <= thresh
b = s[2]
assert abs(b[0] - 100) <= thresh
assert abs(b[1] - 300) <= thresh
assert abs(radius(b) - 40) <= thresh
b = s[3]
assert abs(b[0] - 200) <= thresh
assert abs(b[1] - 350) <= thresh
assert abs(radius(b) - 50) <= thresh
def test_blob_doh_log_scale():
img = np.ones((512, 512), dtype=np.uint8)
xs, ys = disk((400, 130), 20)
img[xs, ys] = 255
xs, ys = disk((460, 50), 30)
img[xs, ys] = 255
xs, ys = disk((100, 300), 40)
img[xs, ys] = 255
xs, ys = disk((200, 350), 50)
img[xs, ys] = 255
blobs = blob_doh(
img,
min_sigma=1,
max_sigma=60,
num_sigma=10,
log_scale=True,
threshold=.05)
def radius(x):
return x[2]
s = sorted(blobs, key=radius)
thresh = 10
b = s[0]
assert abs(b[0] - 400) <= thresh
assert abs(b[1] - 130) <= thresh
assert abs(radius(b) - 20) <= thresh
b = s[2]
assert abs(b[0] - 460) <= thresh
assert abs(b[1] - 50) <= thresh
assert abs(radius(b) - 30) <= thresh
b = s[1]
assert abs(b[0] - 100) <= thresh
assert abs(b[1] - 300) <= thresh
assert abs(radius(b) - 40) <= thresh
b = s[3]
assert abs(b[0] - 200) <= thresh
assert abs(b[1] - 350) <= thresh
assert abs(radius(b) - 50) <= thresh
def test_blob_doh_no_peaks():
# Testing no peaks
img_empty = np.zeros((100, 100))
assert blob_doh(img_empty).size == 0
def test_blob_doh_overlap():
img = np.ones((256, 256), dtype=np.uint8)
xs, ys = disk((100, 100), 20)
img[xs, ys] = 255
xs, ys = disk((120, 100), 30)
img[xs, ys] = 255
blobs = blob_doh(
img,
min_sigma=1,
max_sigma=60,
num_sigma=10,
threshold=.05
)
assert len(blobs) == 1
def test_blob_log_overlap_3d():
r1, r2 = 7, 6
pad1, pad2 = 11, 12
blob1 = ellipsoid(r1, r1, r1)
blob1 = np.pad(blob1, pad1, mode='constant')
blob2 = ellipsoid(r2, r2, r2)
blob2 = np.pad(blob2, [(pad2, pad2), (pad2 - 9, pad2 + 9),
(pad2, pad2)],
mode='constant')
im3 = np.logical_or(blob1, blob2)
blobs = blob_log(im3, min_sigma=2, max_sigma=10, overlap=0.1)
assert len(blobs) == 1
def test_blob_overlap_3d_anisotropic():
# Two spheres with distance between centers equal to radius
# One sphere is much smaller than the other so about half of it is within
# the bigger sphere.
s3 = math.sqrt(3)
overlap = _blob_overlap(np.array([0, 0, 0, 2 / s3, 10 / s3, 10 / s3]),
np.array([0, 0, 10, 0.2 / s3, 1 / s3, 1 / s3]),
sigma_dim=3)
assert_almost_equal(overlap, 0.48125)
overlap = _blob_overlap(np.array([0, 0, 0, 2 / s3, 10 / s3, 10 / s3]),
np.array([2, 0, 0, 0.2 / s3, 1 / s3, 1 / s3]),
sigma_dim=3)
assert_almost_equal(overlap, 0.48125)
def test_blob_log_anisotropic():
image = np.zeros((50, 50))
image[20, 10:20] = 1
isotropic_blobs = blob_log(image, min_sigma=0.5, max_sigma=2, num_sigma=3)
assert len(isotropic_blobs) > 1 # many small blobs found in line
ani_blobs = blob_log(image, min_sigma=[0.5, 5], max_sigma=[2, 20],
num_sigma=3) # 10x anisotropy, line is 1x10
assert len(ani_blobs) == 1 # single anisotropic blob found
def test_blob_log_overlap_3d_anisotropic():
r1, r2 = 7, 6
pad1, pad2 = 11, 12
blob1 = ellipsoid(r1, r1, r1)
blob1 = np.pad(blob1, pad1, mode='constant')
blob2 = ellipsoid(r2, r2, r2)
blob2 = np.pad(blob2, [(pad2, pad2), (pad2 - 9, pad2 + 9),
(pad2, pad2)],
mode='constant')
im3 = np.logical_or(blob1, blob2)
blobs = blob_log(im3, min_sigma=[2, 2.01, 2.005],
max_sigma=10, overlap=0.1)
assert len(blobs) == 1
# Two circles with distance between centers equal to radius
overlap = _blob_overlap(np.array([0, 0, 10 / math.sqrt(2)]),
np.array([0, 10, 10 / math.sqrt(2)]))
assert_almost_equal(overlap,
1./math.pi * (2 * math.acos(1./2) - math.sqrt(3)/2.))
def test_no_blob():
im = np.zeros((10, 10))
blobs = blob_log(im, min_sigma=2, max_sigma=5, num_sigma=4)
assert len(blobs) == 0

View File

@@ -1,80 +0,0 @@
import pytest
import numpy as np
from skimage._shared.testing import assert_array_equal
from skimage import data
from skimage.feature import BRIEF, corner_peaks, corner_harris
from skimage._shared import testing
def test_color_image_unsupported_error():
"""Brief descriptors can be evaluated on gray-scale images only."""
img = np.zeros((20, 20, 3))
keypoints = np.asarray([[7, 5], [11, 13]])
with testing.raises(ValueError):
BRIEF().extract(img, keypoints)
@pytest.mark.parametrize('dtype', ['float32', 'float64', 'uint8', 'int'])
def test_normal_mode(dtype):
"""Verify the computed BRIEF descriptors with expected for normal mode."""
img = data.coins().astype(dtype)
keypoints = corner_peaks(corner_harris(img), min_distance=5,
threshold_abs=0, threshold_rel=0.1)
extractor = BRIEF(descriptor_size=8, sigma=2)
extractor.extract(img, keypoints[:8])
expected = np.array([[1, 1, 1, 0, 1, 1, 0, 1],
[0, 1, 1, 0, 1, 1, 0, 0],
[1, 1, 1, 0, 1, 1, 0, 1],
[0, 0, 0, 1, 0, 0, 1, 0],
[0, 1, 1, 0, 1, 1, 0, 0],
[0, 1, 1, 0, 1, 1, 1, 0],
[1, 1, 1, 0, 1, 1, 0, 1],
[1, 0, 1, 0, 0, 1, 1, 0]], dtype=bool)
assert_array_equal(extractor.descriptors, expected)
@pytest.mark.parametrize('dtype', ['float32', 'float64', 'uint8', 'int'])
def test_uniform_mode(dtype):
"""Verify the computed BRIEF descriptors with expected for uniform mode."""
img = data.coins().astype(dtype)
keypoints = corner_peaks(corner_harris(img), min_distance=5,
threshold_abs=0, threshold_rel=0.1)
extractor = BRIEF(descriptor_size=8, sigma=2, mode='uniform')
extractor.extract(img, keypoints[:8])
expected = np.array([[0, 1, 0, 1, 0, 1, 1, 0],
[0, 1, 0, 0, 0, 1, 0, 1],
[0, 1, 0, 0, 0, 1, 1, 1],
[1, 0, 1, 0, 1, 0, 1, 1],
[0, 0, 1, 0, 0, 1, 0, 1],
[0, 1, 0, 1, 0, 1, 0, 1],
[0, 1, 0, 0, 0, 1, 1, 1],
[1, 0, 1, 1, 1, 0, 0, 1]], dtype=bool)
assert_array_equal(extractor.descriptors, expected)
def test_unsupported_mode():
with testing.raises(ValueError):
BRIEF(mode='foobar')
@pytest.mark.parametrize('dtype', ['float32', 'float64', 'uint8', 'int'])
def test_border(dtype):
img = np.zeros((100, 100), dtype=dtype)
keypoints = np.array([[1, 1], [20, 20], [50, 50], [80, 80]])
extractor = BRIEF(patch_size=41)
extractor.extract(img, keypoints)
assert extractor.descriptors.shape[0] == 3
assert_array_equal(extractor.mask, (False, True, True, True))

View File

@@ -1,131 +0,0 @@
import unittest
import numpy as np
from skimage._shared.testing import assert_equal
from scipy.ndimage import binary_dilation, binary_erosion
from skimage import data, feature
from skimage.util import img_as_float
class TestCanny(unittest.TestCase):
def test_00_00_zeros(self):
'''Test that the Canny filter finds no points for a blank field'''
result = feature.canny(np.zeros((20, 20)), 4, 0, 0, np.ones((20, 20),
bool))
self.assertFalse(np.any(result))
def test_00_01_zeros_mask(self):
'''Test that the Canny filter finds no points in a masked image'''
result = (feature.canny(np.random.uniform(size=(20, 20)), 4, 0, 0,
np.zeros((20, 20), bool)))
self.assertFalse(np.any(result))
def test_01_01_circle(self):
'''Test that the Canny filter finds the outlines of a circle'''
i, j = np.mgrid[-200:200, -200:200].astype(float) / 200
c = np.abs(np.sqrt(i * i + j * j) - .5) < .02
result = feature.canny(c.astype(float), 4, 0, 0, np.ones(c.shape, bool))
#
# erode and dilate the circle to get rings that should contain the
# outlines
#
cd = binary_dilation(c, iterations=3)
ce = binary_erosion(c, iterations=3)
cde = np.logical_and(cd, np.logical_not(ce))
self.assertTrue(np.all(cde[result]))
#
# The circle has a radius of 100. There are two rings here, one
# for the inside edge and one for the outside. So that's
# 100 * 2 * 2 * 3 for those places where pi is still 3.
# The edge contains both pixels if there's a tie, so we
# bump the count a little.
point_count = np.sum(result)
self.assertTrue(point_count > 1200)
self.assertTrue(point_count < 1600)
def test_01_02_circle_with_noise(self):
'''Test that the Canny filter finds the circle outlines
in a noisy image'''
np.random.seed(0)
i, j = np.mgrid[-200:200, -200:200].astype(float) / 200
c = np.abs(np.sqrt(i * i + j * j) - .5) < .02
cf = c.astype(float) * .5 + np.random.uniform(size=c.shape) * .5
result = feature.canny(cf, 4, .1, .2, np.ones(c.shape, bool))
#
# erode and dilate the circle to get rings that should contain the
# outlines
#
cd = binary_dilation(c, iterations=4)
ce = binary_erosion(c, iterations=4)
cde = np.logical_and(cd, np.logical_not(ce))
self.assertTrue(np.all(cde[result]))
point_count = np.sum(result)
self.assertTrue(point_count > 1200)
self.assertTrue(point_count < 1600)
def test_image_shape(self):
self.assertRaises(ValueError, feature.canny, np.zeros((20, 20, 20)), 4,
0, 0)
def test_mask_none(self):
result1 = feature.canny(np.zeros((20, 20)), 4, 0, 0, np.ones((20, 20),
bool))
result2 = feature.canny(np.zeros((20, 20)), 4, 0, 0)
self.assertTrue(np.all(result1 == result2))
def test_use_quantiles(self):
image = img_as_float(data.camera()[::100, ::100])
# Correct output produced manually with quantiles
# of 0.8 and 0.6 for high and low respectively
correct_output = np.array(
[[False, False, False, False, False, False],
[False, True, True, True, False, False],
[False, False, False, True, False, False],
[False, False, False, True, False, False],
[False, False, True, True, False, False],
[False, False, False, False, False, False]])
result = feature.canny(image, low_threshold=0.6, high_threshold=0.8,
use_quantiles=True)
assert_equal(result, correct_output)
def test_img_all_ones(self):
image = np.ones((10, 10))
assert np.all(feature.canny(image) == 0)
def test_invalid_use_quantiles(self):
image = img_as_float(data.camera()[::50, ::50])
self.assertRaises(ValueError, feature.canny, image, use_quantiles=True,
low_threshold=0.5, high_threshold=3.6)
self.assertRaises(ValueError, feature.canny, image, use_quantiles=True,
low_threshold=-5, high_threshold=0.5)
self.assertRaises(ValueError, feature.canny, image, use_quantiles=True,
low_threshold=99, high_threshold=0.9)
self.assertRaises(ValueError, feature.canny, image, use_quantiles=True,
low_threshold=0.5, high_threshold=-100)
# Example from issue #4282
image = data.camera()
self.assertRaises(ValueError, feature.canny, image, use_quantiles=True,
low_threshold=50, high_threshold=150)
def test_dtype(self):
"""Check that the same output is produced regardless of image dtype."""
image_uint8 = data.camera()
image_float = img_as_float(image_uint8)
result_uint8 = feature.canny(image_uint8)
result_float = feature.canny(image_float)
assert_equal(result_uint8, result_float)
low = 0.1
high = 0.2
assert_equal(feature.canny(image_float, 1.0, low, high),
feature.canny(image_uint8, 1.0, 255 * low, 255 * high))

View File

@@ -1,22 +0,0 @@
import skimage.data as data
from skimage.feature import Cascade
def test_detector_astronaut():
# Load the trained file from the module root.
trained_file = data.lbp_frontal_face_cascade_filename()
# Initialize the detector cascade.
detector = Cascade(trained_file)
img = data.astronaut()
detected = detector.detect_multi_scale(img=img,
scale_factor=1.2,
step_ratio=1,
min_size=(60, 60),
max_size=(123, 123))
assert len(detected) == 1, 'One face should be detected.'

View File

@@ -1,103 +0,0 @@
import numpy as np
from skimage._shared.testing import assert_array_equal
from skimage.data import moon
from skimage.feature import CENSURE
from skimage._shared.testing import test_parallel
from skimage._shared import testing
from skimage.transform import rescale
img = moon()
np.random.seed(0)
def test_censure_on_rectangular_images():
"""Censure feature detector should work on 2D image of any shape."""
rect_image = np.random.rand(300, 200)
square_image = np.random.rand(200, 200)
CENSURE().detect(square_image)
CENSURE().detect(rect_image)
def test_keypoints_censure_color_image_unsupported_error():
"""Censure keypoints can be extracted from gray-scale images only."""
with testing.raises(ValueError):
CENSURE().detect(np.zeros((20, 20, 3)))
def test_keypoints_censure_mode_validity_error():
"""Mode argument in keypoints_censure can be either DoB, Octagon or
STAR."""
with testing.raises(ValueError):
CENSURE(mode='dummy')
def test_keypoints_censure_scale_range_error():
"""Difference between the the max_scale and min_scale parameters in
keypoints_censure should be greater than or equal to two."""
with testing.raises(ValueError):
CENSURE(min_scale=1, max_scale=2)
def test_keypoints_censure_moon_image_dob():
"""Verify the actual Censure keypoints and their corresponding scale with
the expected values for DoB filter."""
detector = CENSURE()
detector.detect(img)
expected_keypoints = np.array([[ 21, 497],
[ 36, 46],
[119, 350],
[185, 177],
[287, 250],
[357, 239],
[463, 116],
[464, 132],
[467, 260]])
expected_scales = np.array([3, 4, 4, 2, 2, 3, 2, 2, 2])
assert_array_equal(expected_keypoints, detector.keypoints)
assert_array_equal(expected_scales, detector.scales)
@test_parallel()
def test_keypoints_censure_moon_image_octagon():
"""Verify the actual Censure keypoints and their corresponding scale with
the expected values for Octagon filter."""
detector = CENSURE(mode='octagon')
# quarter scale image for speed
detector.detect(rescale(img, 0.25,
anti_aliasing=False,
mode='constant'))
expected_keypoints = np.array([[ 23, 27],
[ 29, 89],
[ 31, 87],
[106, 59],
[111, 67]])
expected_scales = np.array([3, 2, 5, 2, 4])
assert_array_equal(expected_keypoints, detector.keypoints)
assert_array_equal(expected_scales, detector.scales)
def test_keypoints_censure_moon_image_star():
"""Verify the actual Censure keypoints and their corresponding scale with
the expected values for STAR filter."""
detector = CENSURE(mode='star')
# quarter scale image for speed
detector.detect(rescale(img, 0.25,
anti_aliasing=False,
mode='constant'))
expected_keypoints = np.array([[ 23, 27],
[ 29, 89],
[ 30, 86],
[107, 59],
[109, 64],
[111, 67],
[113, 70]])
expected_scales = np.array([3, 2, 4, 2, 5, 3, 2])
assert_array_equal(expected_keypoints, detector.keypoints)
assert_array_equal(expected_scales, detector.scales)

View File

@@ -1,651 +0,0 @@
import numpy as np
import pytest
from numpy.testing import assert_almost_equal, assert_array_equal, assert_equal
from skimage import data, draw, img_as_float
from skimage._shared._warnings import expected_warnings
from skimage._shared.testing import test_parallel
from skimage._shared.utils import _supported_float_type
from skimage.color import rgb2gray
from skimage.feature import (corner_fast, corner_foerstner, corner_harris,
corner_kitchen_rosenfeld, corner_moravec,
corner_orientations, corner_peaks,
corner_shi_tomasi, corner_subpix, hessian_matrix,
hessian_matrix_det, hessian_matrix_eigvals,
peak_local_max, shape_index, structure_tensor,
structure_tensor_eigenvalues)
from skimage.morphology import cube, octagon
@pytest.fixture
def im3d():
r = 10
pad = 10
im3 = draw.ellipsoid(r, r, r)
im3 = np.pad(im3, pad, mode='constant').astype(np.uint8)
return im3
@pytest.mark.parametrize('dtype', [np.float16, np.float32, np.float64])
def test_structure_tensor(dtype):
square = np.zeros((5, 5), dtype=dtype)
square[2, 2] = 1
Arr, Arc, Acc = structure_tensor(square, sigma=0.1, order='rc')
out_dtype = _supported_float_type(dtype)
assert all(a.dtype == out_dtype for a in (Arr, Arc, Acc))
assert_array_equal(Acc, np.array([[0, 0, 0, 0, 0],
[0, 1, 0, 1, 0],
[0, 4, 0, 4, 0],
[0, 1, 0, 1, 0],
[0, 0, 0, 0, 0]]))
assert_array_equal(Arc, np.array([[0, 0, 0, 0, 0],
[0, 1, 0, -1, 0],
[0, 0, 0, -0, 0],
[0, -1, -0, 1, 0],
[0, 0, 0, 0, 0]]))
assert_array_equal(Arr, np.array([[0, 0, 0, 0, 0],
[0, 1, 4, 1, 0],
[0, 0, 0, 0, 0],
[0, 1, 4, 1, 0],
[0, 0, 0, 0, 0]]))
@pytest.mark.parametrize('dtype', [np.float16, np.float32, np.float64])
def test_structure_tensor_3d(dtype):
cube = np.zeros((5, 5, 5), dtype=dtype)
cube[2, 2, 2] = 1
A_elems = structure_tensor(cube, sigma=0.1)
assert all(a.dtype == _supported_float_type(dtype) for a in A_elems)
assert_equal(len(A_elems), 6)
assert_array_equal(A_elems[0][:, 1, :], np.array([[0, 0, 0, 0, 0],
[0, 1, 4, 1, 0],
[0, 0, 0, 0, 0],
[0, 1, 4, 1, 0],
[0, 0, 0, 0, 0]]))
assert_array_equal(A_elems[0][1], np.array([[0, 0, 0, 0, 0],
[0, 1, 4, 1, 0],
[0, 4, 16, 4, 0],
[0, 1, 4, 1, 0],
[0, 0, 0, 0, 0]]))
assert_array_equal(A_elems[3][2], np.array([[0, 0, 0, 0, 0],
[0, 4, 16, 4, 0],
[0, 0, 0, 0, 0],
[0, 4, 16, 4, 0],
[0, 0, 0, 0, 0]]))
def test_structure_tensor_3d_rc_only():
cube = np.zeros((5, 5, 5))
with pytest.raises(ValueError):
structure_tensor(cube, sigma=0.1, order='xy')
A_elems_rc = structure_tensor(cube, sigma=0.1, order='rc')
A_elems_none = structure_tensor(cube, sigma=0.1)
assert_array_equal(A_elems_rc, A_elems_none)
def test_structure_tensor_orders():
square = np.zeros((5, 5))
square[2, 2] = 1
A_elems_default = structure_tensor(square, sigma=0.1)
A_elems_xy = structure_tensor(square, sigma=0.1, order='xy')
A_elems_rc = structure_tensor(square, sigma=0.1, order='rc')
assert_array_equal(A_elems_rc, A_elems_default)
assert_array_equal(A_elems_xy, A_elems_default[::-1])
@pytest.mark.parametrize('ndim', [2, 3])
def test_structure_tensor_sigma(ndim):
img = np.zeros((5,) * ndim)
img[[2] * ndim] = 1
A_default = structure_tensor(img, sigma=0.1, order='rc')
A_tuple = structure_tensor(img, sigma=(0.1,) * ndim, order='rc')
A_list = structure_tensor(img, sigma=[0.1] * ndim, order='rc')
assert_array_equal(A_tuple, A_default)
assert_array_equal(A_list, A_default)
with pytest.raises(ValueError):
structure_tensor(img, sigma=(0.1,) * (ndim - 1), order='rc')
with pytest.raises(ValueError):
structure_tensor(img, sigma=[0.1] * (ndim + 1), order='rc')
@pytest.mark.parametrize('dtype', [np.float16, np.float32, np.float64])
def test_hessian_matrix(dtype):
square = np.zeros((5, 5), dtype=dtype)
square[2, 2] = 4
Hrr, Hrc, Hcc = hessian_matrix(square, sigma=0.1, order='rc',
use_gaussian_derivatives=False)
out_dtype = _supported_float_type(dtype)
assert all(a.dtype == out_dtype for a in (Hrr, Hrc, Hcc))
assert_almost_equal(Hrr, np.array([[0, 0, 2, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, -2, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 2, 0, 0]]))
assert_almost_equal(Hrc, np.array([[0, 0, 0, 0, 0],
[0, 1, 0, -1, 0],
[0, 0, 0, 0, 0],
[0, -1, 0, 1, 0],
[0, 0, 0, 0, 0]]))
assert_almost_equal(Hcc, np.array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[2, 0, -2, 0, 2],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]))
with expected_warnings(["use_gaussian_derivatives currently defaults"]):
# FutureWarning warning when use_gaussian_derivatives is not
# specified.
hessian_matrix(square, sigma=0.1, order='rc')
@pytest.mark.parametrize('use_gaussian_derivatives', [False, True])
def test_hessian_matrix_order(use_gaussian_derivatives):
square = np.zeros((5, 5), dtype=float)
square[2, 2] = 4
Hxx, Hxy, Hyy = hessian_matrix(
square, sigma=0.1, order="xy",
use_gaussian_derivatives=use_gaussian_derivatives)
Hrr, Hrc, Hcc = hessian_matrix(
square, sigma=0.1, order="rc",
use_gaussian_derivatives=use_gaussian_derivatives)
# verify results are equivalent, just reversed in order
assert_array_equal(Hxx, Hcc)
assert_array_equal(Hxy, Hrc)
assert_array_equal(Hyy, Hrr)
def test_hessian_matrix_3d():
cube = np.zeros((5, 5, 5))
cube[2, 2, 2] = 4
Hs = hessian_matrix(cube, sigma=0.1, order='rc',
use_gaussian_derivatives=False)
assert len(Hs) == 6, (f"incorrect number of Hessian images ({len(Hs)}) for 3D")
# This test didn't catch the fix in gh-6624 (passes with and without) ...
assert_almost_equal(Hs[2][:, 2, :], np.array([[0, 0, 0, 0, 0],
[0, 1, 0, -1, 0],
[0, 0, 0, 0, 0],
[0, -1, 0, 1, 0],
[0, 0, 0, 0, 0]]))
# ... so we add another test that fails for the not-fixed hessian_matrix
assert_almost_equal(Hs[0][:, 2, :], np.array([[0, 0, 2, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, -2, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 2, 0, 0]]))
@pytest.mark.parametrize('use_gaussian_derivatives', [False, True])
def test_hessian_matrix_3d_xy(use_gaussian_derivatives):
img = np.ones((5, 5, 5))
# order="xy" is only permitted for 2D
with pytest.raises(ValueError):
hessian_matrix(img, sigma=0.1, order="xy",
use_gaussian_derivatives=use_gaussian_derivatives)
with pytest.raises(ValueError):
hessian_matrix(img, sigma=0.1, order='nonexistant',
use_gaussian_derivatives=use_gaussian_derivatives)
@pytest.mark.parametrize('dtype', [np.float16, np.float32, np.float64])
def test_structure_tensor_eigenvalues(dtype):
square = np.zeros((5, 5), dtype=dtype)
square[2, 2] = 1
A_elems = structure_tensor(square, sigma=0.1, order='rc')
l1, l2 = structure_tensor_eigenvalues(A_elems)
out_dtype = _supported_float_type(dtype)
assert all(a.dtype == out_dtype for a in (l1, l2))
assert_array_equal(l1, np.array([[0, 0, 0, 0, 0],
[0, 2, 4, 2, 0],
[0, 4, 0, 4, 0],
[0, 2, 4, 2, 0],
[0, 0, 0, 0, 0]]))
assert_array_equal(l2, np.array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]))
def test_structure_tensor_eigenvalues_3d():
image = np.pad(cube(9), 5, mode='constant') * 1000
boundary = (np.pad(cube(9), 5, mode='constant')
- np.pad(cube(7), 6, mode='constant')).astype(bool)
A_elems = structure_tensor(image, sigma=0.1)
e0, e1, e2 = structure_tensor_eigenvalues(A_elems)
# e0 should detect facets
assert np.all(e0[boundary] != 0)
@pytest.mark.parametrize('dtype', [np.float16, np.float32, np.float64])
def test_hessian_matrix_eigvals(dtype):
square = np.zeros((5, 5), dtype=dtype)
square[2, 2] = 4
H = hessian_matrix(square, sigma=0.1, order='rc',
use_gaussian_derivatives=False)
l1, l2 = hessian_matrix_eigvals(H)
out_dtype = _supported_float_type(dtype)
assert all(a.dtype == out_dtype for a in (l1, l2))
assert_almost_equal(l1, np.array([[0, 0, 2, 0, 0],
[0, 1, 0, 1, 0],
[2, 0, -2, 0, 2],
[0, 1, 0, 1, 0],
[0, 0, 2, 0, 0]]))
assert_almost_equal(l2, np.array([[0, 0, 0, 0, 0],
[0, -1, 0, -1, 0],
[0, 0, -2, 0, 0],
[0, -1, 0, -1, 0],
[0, 0, 0, 0, 0]]))
@pytest.mark.parametrize('dtype', [np.float16, np.float32, np.float64])
def test_hessian_matrix_eigvals_3d(im3d, dtype):
im3d = im3d.astype(dtype, copy=False)
H = hessian_matrix(im3d, use_gaussian_derivatives=False)
E = hessian_matrix_eigvals(H)
out_dtype = _supported_float_type(dtype)
assert all(a.dtype == out_dtype for a in E)
# test descending order:
e0, e1, e2 = E
assert np.all(e0 >= e1) and np.all(e1 >= e2)
E0, E1, E2 = E[:, E.shape[1] // 2] # cross section
row_center, col_center = np.array(E0.shape) // 2
circles = [draw.circle_perimeter(row_center, col_center, radius,
shape=E0.shape)
for radius in range(1, E0.shape[1] // 2 - 1)]
response0 = np.array([np.mean(E0[c]) for c in circles])
response2 = np.array([np.mean(E2[c]) for c in circles])
# eigenvalues are negative just inside the sphere, positive just outside
assert np.argmin(response2) < np.argmax(response0)
assert np.min(response2) < 0
assert np.max(response0) > 0
@test_parallel()
def test_hessian_matrix_det():
image = np.zeros((5, 5))
image[2, 2] = 1
det = hessian_matrix_det(image, 5)
assert_almost_equal(det, 0, decimal=3)
@pytest.mark.parametrize('dtype', [np.float16, np.float32, np.float64])
def test_hessian_matrix_det_3d(im3d, dtype):
im3d = im3d.astype(dtype, copy=False)
D = hessian_matrix_det(im3d)
assert D.dtype == _supported_float_type(dtype)
D0 = D[D.shape[0] // 2]
row_center, col_center = np.array(D0.shape) // 2
# testing in 3D is hard. We test this by showing that you get the
# expected flat-then-low-then-high 2nd derivative response in a circle
# around the midplane of the sphere.
circles = [draw.circle_perimeter(row_center, col_center, r, shape=D0.shape)
for r in range(1, D0.shape[1] // 2 - 1)]
response = np.array([np.mean(D0[c]) for c in circles])
lowest = np.argmin(response)
highest = np.argmax(response)
assert lowest < highest
assert response[lowest] < 0
assert response[highest] > 0
def test_shape_index():
# software floating point arm doesn't raise a warning on divide by zero
# https://github.com/scikit-image/scikit-image/issues/3335
square = np.zeros((5, 5))
square[2, 2] = 4
with expected_warnings([r'divide by zero|\A\Z', r'invalid value|\A\Z']):
s = shape_index(square, sigma=0.1)
assert_almost_equal(
s, np.array([[ np.nan, np.nan, -0.5, np.nan, np.nan],
[ np.nan, 0, np.nan, 0, np.nan],
[ -0.5, np.nan, -1, np.nan, -0.5],
[ np.nan, 0, np.nan, 0, np.nan],
[ np.nan, np.nan, -0.5, np.nan, np.nan]])
)
@test_parallel()
def test_square_image():
im = np.zeros((50, 50)).astype(float)
im[:25, :25] = 1.
# Moravec
results = corner_moravec(im) > 0
# interest points along edge
assert np.count_nonzero(results) == 92
# Harris
results = peak_local_max(corner_harris(im, method='k'),
min_distance=10, threshold_rel=0)
# interest at corner
assert len(results) == 1
results = peak_local_max(corner_harris(im, method='eps'),
min_distance=10, threshold_rel=0)
# interest at corner
assert len(results) == 1
# Shi-Tomasi
results = peak_local_max(corner_shi_tomasi(im),
min_distance=10, threshold_rel=0)
# interest at corner
assert len(results) == 1
@pytest.mark.parametrize('dtype', [np.float16, np.float32, np.float64])
@pytest.mark.parametrize(
'func',
[
corner_moravec,
corner_harris,
corner_shi_tomasi,
corner_kitchen_rosenfeld,
]
)
def test_corner_dtype(dtype, func):
im = np.zeros((50, 50), dtype=dtype)
im[:25, :25] = 1.
out_dtype = _supported_float_type(dtype)
corners = func(im)
assert corners.dtype == out_dtype
@pytest.mark.parametrize('dtype', [np.float16, np.float32, np.float64])
def test_corner_foerstner_dtype(dtype):
im = np.zeros((50, 50), dtype=dtype)
im[:25, :25] = 1.
out_dtype = _supported_float_type(dtype)
assert all(arr.dtype == out_dtype for arr in corner_foerstner(im))
def test_noisy_square_image():
im = np.zeros((50, 50)).astype(float)
im[:25, :25] = 1.
np.random.seed(seed=1234)
im = im + np.random.uniform(size=im.shape) * .2
# Moravec
results = peak_local_max(corner_moravec(im),
min_distance=10, threshold_rel=0)
# undefined number of interest points
assert results.any()
# Harris
results = peak_local_max(corner_harris(im, method='k'),
min_distance=10, threshold_rel=0)
assert len(results) == 1
results = peak_local_max(corner_harris(im, method='eps'),
min_distance=10, threshold_rel=0)
assert len(results) == 1
# Shi-Tomasi
results = peak_local_max(corner_shi_tomasi(im, sigma=1.5),
min_distance=10, threshold_rel=0)
assert len(results) == 1
def test_squared_dot():
im = np.zeros((50, 50))
im[4:8, 4:8] = 1
im = img_as_float(im)
# Moravec fails
# Harris
results = peak_local_max(corner_harris(im),
min_distance=10, threshold_rel=0)
assert (results == np.array([[6, 6]])).all()
# Shi-Tomasi
results = peak_local_max(corner_shi_tomasi(im),
min_distance=10, threshold_rel=0)
assert (results == np.array([[6, 6]])).all()
def test_rotated_img():
"""
The harris filter should yield the same results with an image and it's
rotation.
"""
im = img_as_float(data.astronaut().mean(axis=2))
im_rotated = im.T
# Moravec
results = np.nonzero(corner_moravec(im))
results_rotated = np.nonzero(corner_moravec(im_rotated))
assert (np.sort(results[0]) == np.sort(results_rotated[1])).all()
assert (np.sort(results[1]) == np.sort(results_rotated[0])).all()
# Harris
results = np.nonzero(corner_harris(im))
results_rotated = np.nonzero(corner_harris(im_rotated))
assert (np.sort(results[0]) == np.sort(results_rotated[1])).all()
assert (np.sort(results[1]) == np.sort(results_rotated[0])).all()
# Shi-Tomasi
results = np.nonzero(corner_shi_tomasi(im))
results_rotated = np.nonzero(corner_shi_tomasi(im_rotated))
assert (np.sort(results[0]) == np.sort(results_rotated[1])).all()
assert (np.sort(results[1]) == np.sort(results_rotated[0])).all()
@pytest.mark.parametrize('dtype', [np.float16, np.float32, np.float64])
def test_subpix_edge(dtype):
img = np.zeros((50, 50), dtype=dtype)
img[:25, :25] = 255
img[25:, 25:] = 255
corner = peak_local_max(corner_harris(img),
min_distance=10, threshold_rel=0, num_peaks=1)
subpix = corner_subpix(img, corner)
assert subpix.dtype == _supported_float_type(dtype)
assert_array_equal(subpix[0], (24.5, 24.5))
def test_subpix_dot():
img = np.zeros((50, 50))
img[25, 25] = 255
corner = peak_local_max(corner_harris(img),
min_distance=10, threshold_rel=0, num_peaks=1)
subpix = corner_subpix(img, corner)
assert_array_equal(subpix[0], (25, 25))
def test_subpix_no_class():
img = np.zeros((50, 50))
subpix = corner_subpix(img, np.array([[25, 25]]))
assert_array_equal(subpix[0], (np.nan, np.nan))
img[25, 25] = 1e-10
corner = peak_local_max(corner_harris(img),
min_distance=10, threshold_rel=0, num_peaks=1)
subpix = corner_subpix(img, corner)
assert_array_equal(subpix[0], (np.nan, np.nan))
def test_subpix_border():
img = np.zeros((50, 50))
img[1:25, 1:25] = 255
img[25:-1, 25:-1] = 255
corner = corner_peaks(corner_harris(img), threshold_rel=0)
subpix = corner_subpix(img, corner, window_size=11)
ref = np.array([[24.5, 24.5],
[0.52040816, 0.52040816],
[0.52040816, 24.47959184],
[24.47959184, 0.52040816],
[24.52040816, 48.47959184],
[48.47959184, 24.52040816],
[48.47959184, 48.47959184]])
assert_almost_equal(subpix, ref)
def test_num_peaks():
"""For a bunch of different values of num_peaks, check that
peak_local_max returns exactly the right amount of peaks. Test
is run on the astronaut image in order to produce a sufficient number of
corners.
"""
img_corners = corner_harris(rgb2gray(data.astronaut()))
for i in range(20):
n = np.random.randint(1, 21)
results = peak_local_max(img_corners,
min_distance=10, threshold_rel=0, num_peaks=n)
assert (results.shape[0] == n)
def test_corner_peaks():
response = np.zeros((10, 10))
response[2:5, 2:5] = 1
response[8:10, 0:2] = 1
corners = corner_peaks(response, exclude_border=False, min_distance=10,
threshold_rel=0)
assert corners.shape == (1, 2)
corners = corner_peaks(response, exclude_border=False, min_distance=5,
threshold_rel=0)
assert corners.shape == (2, 2)
corners = corner_peaks(response, exclude_border=False, min_distance=1)
assert corners.shape == (5, 2)
corners = corner_peaks(response, exclude_border=False, min_distance=1,
indices=False)
assert np.sum(corners) == 5
def test_blank_image_nans():
"""Some of the corner detectors had a weakness in terms of returning
NaN when presented with regions of constant intensity. This should
be fixed by now. We test whether each detector returns something
finite in the case of constant input"""
detectors = [corner_moravec, corner_harris, corner_shi_tomasi,
corner_kitchen_rosenfeld, corner_foerstner]
constant_image = np.zeros((20, 20))
for det in detectors:
response = det(constant_image)
assert np.all(np.isfinite(response))
def test_corner_fast_image_unsupported_error():
img = np.zeros((20, 20, 3))
with pytest.raises(ValueError):
corner_fast(img)
@test_parallel()
def test_corner_fast_astronaut():
img = rgb2gray(data.astronaut())
expected = np.array([[444, 310],
[374, 171],
[249, 171],
[492, 139],
[403, 162],
[496, 266],
[362, 328],
[476, 250],
[353, 172],
[346, 279],
[494, 169],
[177, 156],
[413, 181],
[213, 117],
[390, 149],
[140, 205],
[232, 266],
[489, 155],
[387, 195],
[101, 198],
[363, 192],
[364, 147],
[300, 244],
[325, 245],
[141, 242],
[401, 197],
[197, 148],
[339, 242],
[188, 113],
[362, 252],
[379, 183],
[358, 307],
[245, 137],
[369, 159],
[464, 251],
[305, 57],
[223, 375]])
actual = corner_peaks(corner_fast(img, 12, 0.3),
min_distance=10, threshold_rel=0)
assert_array_equal(actual, expected)
def test_corner_orientations_image_unsupported_error():
img = np.zeros((20, 20, 3))
with pytest.raises(ValueError):
corner_orientations(
img,
np.asarray([[7, 7]]), np.ones((3, 3)))
def test_corner_orientations_even_shape_error():
img = np.zeros((20, 20))
with pytest.raises(ValueError):
corner_orientations(
img,
np.asarray([[7, 7]]), np.ones((4, 4)))
@test_parallel()
def test_corner_orientations_astronaut():
img = rgb2gray(data.astronaut())
corners = corner_peaks(corner_fast(img, 11, 0.35),
min_distance=10, threshold_abs=0, threshold_rel=0.1)
expected = np.array([-4.40598471e-01, -1.46554357e+00,
2.39291733e+00, -1.63869275e+00,
1.45931342e+00, -1.64397304e+00,
-1.76069982e+00, 1.09650167e+00,
-1.65449964e+00, 1.19134149e+00,
5.46905279e-02, 2.17103132e+00,
8.12701702e-01, -1.22091334e-01,
-2.01162417e+00, 1.25854853e+00,
3.05330950e+00, 2.01197383e+00,
1.07812134e+00, 3.09780364e+00,
-3.49561988e-01, 2.43573659e+00,
3.14918803e-01, -9.88548213e-01,
-1.88247204e-01, 2.47305654e+00,
-2.99143370e+00, 1.47154532e+00,
-6.61151410e-01, -1.68885773e+00,
-3.09279990e-01, -2.81524886e+00,
-1.75220190e+00, -1.69230287e+00,
-7.52950306e-04])
actual = corner_orientations(img, corners, octagon(3, 2))
assert_almost_equal(actual, expected)
@pytest.mark.parametrize('dtype', [np.float16, np.float32, np.float64])
def test_corner_orientations_square(dtype):
square = np.zeros((12, 12), dtype=dtype)
square[3:9, 3:9] = 1
corners = corner_peaks(corner_fast(square, 9),
min_distance=1, threshold_rel=0)
actual_orientations = corner_orientations(square, corners, octagon(3, 2))
assert actual_orientations.dtype == _supported_float_type(dtype)
actual_orientations_degrees = np.rad2deg(actual_orientations)
expected_orientations_degree = np.array([45, 135, -45, -135])
assert_array_equal(actual_orientations_degrees,
expected_orientations_degree)

View File

@@ -1,104 +0,0 @@
import numpy as np
import pytest
from numpy import sqrt, ceil
from numpy.testing import assert_almost_equal
from skimage import data
from skimage import img_as_float
from skimage.feature import daisy
def test_daisy_color_image_unsupported_error():
img = np.zeros((20, 20, 3))
with pytest.raises(ValueError):
daisy(img)
def test_daisy_desc_dims():
img = img_as_float(data.astronaut()[:128, :128].mean(axis=2))
rings = 2
histograms = 4
orientations = 3
descs = daisy(img, rings=rings, histograms=histograms,
orientations=orientations)
assert(descs.shape[2] == (rings * histograms + 1) * orientations)
rings = 4
histograms = 5
orientations = 13
descs = daisy(img, rings=rings, histograms=histograms,
orientations=orientations)
assert(descs.shape[2] == (rings * histograms + 1) * orientations)
def test_descs_shape():
img = img_as_float(data.astronaut()[:256, :256].mean(axis=2))
radius = 20
step = 8
descs = daisy(img, radius=radius, step=step)
assert(descs.shape[0] == ceil((img.shape[0] - radius * 2) / float(step)))
assert(descs.shape[1] == ceil((img.shape[1] - radius * 2) / float(step)))
img = img[:-1, :-2]
radius = 5
step = 3
descs = daisy(img, radius=radius, step=step)
assert(descs.shape[0] == ceil((img.shape[0] - radius * 2) / float(step)))
assert(descs.shape[1] == ceil((img.shape[1] - radius * 2) / float(step)))
@pytest.mark.parametrize('dtype', [np.float32, np.float64])
def test_daisy_sigmas_and_radii(dtype):
img = data.astronaut()[:64, :64].mean(axis=2).astype(dtype, copy=False)
sigmas = [1, 2, 3]
radii = [1, 2]
descs = daisy(img, sigmas=sigmas, ring_radii=radii)
assert descs.dtype == img.dtype
def test_daisy_incompatible_sigmas_and_radii():
img = img_as_float(data.astronaut()[:64, :64].mean(axis=2))
sigmas = [1, 2]
radii = [1, 2]
with pytest.raises(ValueError):
daisy(img, sigmas=sigmas, ring_radii=radii)
def test_daisy_normalization():
img = img_as_float(data.astronaut()[:64, :64].mean(axis=2))
descs = daisy(img, normalization='l1')
for i in range(descs.shape[0]):
for j in range(descs.shape[1]):
assert_almost_equal(np.sum(descs[i, j, :]), 1)
descs_ = daisy(img)
assert_almost_equal(descs, descs_)
descs = daisy(img, normalization='l2')
for i in range(descs.shape[0]):
for j in range(descs.shape[1]):
assert_almost_equal(sqrt(np.sum(descs[i, j, :] ** 2)), 1)
orientations = 8
descs = daisy(img, orientations=orientations, normalization='daisy')
desc_dims = descs.shape[2]
for i in range(descs.shape[0]):
for j in range(descs.shape[1]):
for k in range(0, desc_dims, orientations):
assert_almost_equal(sqrt(np.sum(
descs[i, j, k:k + orientations] ** 2)), 1)
img = np.zeros((50, 50))
descs = daisy(img, normalization='off')
for i in range(descs.shape[0]):
for j in range(descs.shape[1]):
assert_almost_equal(np.sum(descs[i, j, :]), 0)
with pytest.raises(ValueError):
daisy(img, normalization='does_not_exist')
def test_daisy_visualization():
img = img_as_float(data.astronaut()[:32, :32].mean(axis=2))
descs, descs_img = daisy(img, visualize=True)
assert(descs_img.shape == (32, 32, 3))

View File

@@ -1,158 +0,0 @@
from random import shuffle
import pytest
import numpy as np
from numpy.testing import assert_allclose
from numpy.testing import assert_array_equal
from skimage.transform import integral_image
from skimage.feature import haar_like_feature
from skimage.feature import haar_like_feature_coord
from skimage.feature import draw_haar_like_feature
def test_haar_like_feature_error():
img = np.ones((5, 5), dtype=np.float32)
img_ii = integral_image(img)
feature_type = 'unknown_type'
with pytest.raises(ValueError):
haar_like_feature(img_ii, 0, 0, 5, 5, feature_type=feature_type)
haar_like_feature_coord(5, 5, feature_type=feature_type)
draw_haar_like_feature(img, 0, 0, 5, 5, feature_type=feature_type)
feat_coord, feat_type = haar_like_feature_coord(5, 5, 'type-2-x')
with pytest.raises(ValueError):
haar_like_feature(img_ii, 0, 0, 5, 5, feature_type=feat_type[:3],
feature_coord=feat_coord)
@pytest.mark.parametrize("dtype", [np.uint8, np.int8,
np.float32, np.float64])
@pytest.mark.parametrize("feature_type,shape_feature,expected_feature_value",
[('type-2-x', (84,), [0.]),
('type-2-y', (84,), [0.]),
('type-3-x', (42,), [-5, -4., -3., -2., -1.]),
('type-3-y', (42,), [-5, -4., -3., -2., -1.]),
('type-4', (36,), [0.])])
def test_haar_like_feature(feature_type, shape_feature,
expected_feature_value, dtype):
# test Haar-like feature on a basic one image
img = np.ones((5, 5), dtype=dtype)
img_ii = integral_image(img)
haar_feature = haar_like_feature(img_ii, 0, 0, 5, 5,
feature_type=feature_type)
assert_allclose(np.sort(np.unique(haar_feature)), expected_feature_value)
@pytest.mark.parametrize("dtype", [np.uint8, np.int8,
np.float32, np.float64])
@pytest.mark.parametrize("feature_type", ['type-2-x', 'type-2-y',
'type-3-x', 'type-3-y',
'type-4'])
def test_haar_like_feature_fused_type(dtype, feature_type):
# check that the input type is kept
img = np.ones((5, 5), dtype=dtype)
img_ii = integral_image(img)
expected_dtype = img_ii.dtype
# to avoid overflow, unsigned type are converted to signed
if 'uint' in expected_dtype.name:
expected_dtype = np.dtype(expected_dtype.name.replace('u', ''))
haar_feature = haar_like_feature(img_ii, 0, 0, 5, 5,
feature_type=feature_type)
assert haar_feature.dtype == expected_dtype
def test_haar_like_feature_list():
img = np.ones((5, 5), dtype=np.int8)
img_ii = integral_image(img)
feature_type = ['type-2-x', 'type-2-y', 'type-3-x', 'type-3-y', 'type-4']
haar_list = haar_like_feature(img_ii, 0, 0, 5, 5,
feature_type=feature_type)
haar_all = haar_like_feature(img_ii, 0, 0, 5, 5)
assert_array_equal(haar_list, haar_all)
@pytest.mark.parametrize("feature_type", ['type-2-x', 'type-2-y',
'type-3-x', 'type-3-y',
'type-4',
['type-2-y', 'type-3-x',
'type-4']])
def test_haar_like_feature_precomputed(feature_type):
img = np.ones((5, 5), dtype=np.int8)
img_ii = integral_image(img)
if isinstance(feature_type, list):
# shuffle the index of the feature to be sure that we are output
# the features in the same order
shuffle(feature_type)
feat_coord, feat_type = zip(*[haar_like_feature_coord(5, 5, feat_t)
for feat_t in feature_type])
feat_coord = np.concatenate(feat_coord)
feat_type = np.concatenate(feat_type)
else:
feat_coord, feat_type = haar_like_feature_coord(5, 5, feature_type)
haar_feature_precomputed = haar_like_feature(img_ii, 0, 0, 5, 5,
feature_type=feat_type,
feature_coord=feat_coord)
haar_feature = haar_like_feature(img_ii, 0, 0, 5, 5, feature_type)
assert_array_equal(haar_feature_precomputed, haar_feature)
@pytest.mark.parametrize("feature_type,height,width,expected_coord",
[('type-2-x', 2, 2,
[[[(0, 0), (0, 0)], [(0, 1), (0, 1)]],
[[(0, 0), (1, 0)], [(0, 1), (1, 1)]],
[[(1, 0), (1, 0)], [(1, 1), (1, 1)]]]),
('type-2-y', 2, 2,
[[[(0, 0), (0, 0)], [(1, 0), (1, 0)]],
[[(0, 0), (0, 1)], [(1, 0), (1, 1)]],
[[(0, 1), (0, 1)], [(1, 1), (1, 1)]]]),
('type-3-x', 3, 3,
[[[(0, 0), (0, 0)], [(0, 1), (0, 1)],
[(0, 2), (0, 2)]],
[[(0, 0), (1, 0)], [(0, 1), (1, 1)],
[(0, 2), (1, 2)]],
[[(0, 0), (2, 0)], [(0, 1), (2, 1)],
[(0, 2), (2, 2)]],
[[(1, 0), (1, 0)], [(1, 1), (1, 1)],
[(1, 2), (1, 2)]],
[[(1, 0), (2, 0)], [(1, 1), (2, 1)],
[(1, 2), (2, 2)]],
[[(2, 0), (2, 0)], [(2, 1), (2, 1)],
[(2, 2), (2, 2)]]]),
('type-3-y', 3, 3,
[[[(0, 0), (0, 0)], [(1, 0), (1, 0)],
[(2, 0), (2, 0)]],
[[(0, 0), (0, 1)], [(1, 0), (1, 1)],
[(2, 0), (2, 1)]],
[[(0, 0), (0, 2)], [(1, 0), (1, 2)],
[(2, 0), (2, 2)]],
[[(0, 1), (0, 1)], [(1, 1), (1, 1)],
[(2, 1), (2, 1)]],
[[(0, 1), (0, 2)], [(1, 1), (1, 2)],
[(2, 1), (2, 2)]],
[[(0, 2), (0, 2)], [(1, 2), (1, 2)],
[(2, 2), (2, 2)]]]),
('type-4', 2, 2,
[[[(0, 0), (0, 0)], [(0, 1), (0, 1)],
[(1, 1), (1, 1)], [(1, 0), (1, 0)]]])])
def test_haar_like_feature_coord(feature_type, height, width, expected_coord):
feat_coord, feat_type = haar_like_feature_coord(width, height,
feature_type)
# convert the output to a full numpy array just for comparison
feat_coord = np.array([hf for hf in feat_coord])
assert_array_equal(feat_coord, expected_coord)
assert np.all(feat_type == feature_type)
@pytest.mark.parametrize("max_n_features,nnz_values", [(None, 46),
(1, 4)])
def test_draw_haar_like_feature(max_n_features, nnz_values):
img = np.zeros((5, 5), dtype=np.float32)
coord, _ = haar_like_feature_coord(5, 5, 'type-4')
image = draw_haar_like_feature(img, 0, 0, 5, 5, coord,
max_n_features=max_n_features,
random_state=0)
assert image.shape == (5, 5, 3)
assert np.count_nonzero(image) == nnz_values

View File

@@ -1,289 +0,0 @@
import numpy as np
import pytest
from numpy.testing import assert_almost_equal
from skimage import color, data, draw, feature, img_as_float
from skimage._shared import filters
from skimage._shared.testing import fetch
from skimage._shared.utils import _supported_float_type
def test_hog_output_size():
img = img_as_float(data.astronaut()[:256, :].mean(axis=2))
fd = feature.hog(img, orientations=9, pixels_per_cell=(8, 8),
cells_per_block=(1, 1), block_norm='L1')
assert len(fd) == 9 * (256 // 8) * (512 // 8)
@pytest.mark.parametrize('dtype', [np.float32, np.float64])
def test_hog_output_correctness_l1_norm(dtype):
img = color.rgb2gray(data.astronaut()).astype(dtype=dtype, copy=False)
correct_output = np.load(fetch('data/astronaut_GRAY_hog_L1.npy'))
output = feature.hog(img, orientations=9, pixels_per_cell=(8, 8),
cells_per_block=(3, 3), block_norm='L1',
feature_vector=True, transform_sqrt=False,
visualize=False)
float_dtype = _supported_float_type(dtype)
assert output.dtype == float_dtype
decimal = 7 if float_dtype == np.float64 else 5
assert_almost_equal(output, correct_output, decimal=decimal)
@pytest.mark.parametrize('dtype', [np.float32, np.float64])
def test_hog_output_correctness_l2hys_norm(dtype):
img = color.rgb2gray(data.astronaut()).astype(dtype=dtype, copy=False)
correct_output = np.load(fetch('data/astronaut_GRAY_hog_L2-Hys.npy'))
output = feature.hog(img, orientations=9, pixels_per_cell=(8, 8),
cells_per_block=(3, 3), block_norm='L2-Hys',
feature_vector=True, transform_sqrt=False,
visualize=False)
float_dtype = _supported_float_type(dtype)
assert output.dtype == float_dtype
decimal = 7 if float_dtype == np.float64 else 5
assert_almost_equal(output, correct_output, decimal=decimal)
def test_hog_image_size_cell_size_mismatch():
image = data.camera()[:150, :200]
fd = feature.hog(image, orientations=9, pixels_per_cell=(8, 8),
cells_per_block=(1, 1), block_norm='L1')
assert len(fd) == 9 * (150 // 8) * (200 // 8)
def test_hog_odd_cell_size():
img = np.zeros((3, 3))
img[2, 2] = 1
correct_output = np.zeros((9, ))
correct_output[0] = 0.5
correct_output[4] = 0.5
output = feature.hog(img, pixels_per_cell=(3, 3),
cells_per_block=(1, 1), block_norm='L1')
assert_almost_equal(output, correct_output, decimal=1)
def test_hog_basic_orientations_and_data_types():
# scenario:
# 1) create image (with float values) where upper half is filled by
# zeros, bottom half by 100
# 2) create unsigned integer version of this image
# 3) calculate feature.hog() for both images, both with 'transform_sqrt'
# option enabled and disabled
# 4) verify that all results are equal where expected
# 5) verify that computed feature vector is as expected
# 6) repeat the scenario for 90, 180 and 270 degrees rotated images
# size of testing image
width = height = 35
image0 = np.zeros((height, width), dtype='float')
image0[height // 2:] = 100
for rot in range(4):
# rotate by 0, 90, 180 and 270 degrees
image_float = np.rot90(image0, rot)
# create uint8 image from image_float
image_uint8 = image_float.astype('uint8')
(hog_float, hog_img_float) = feature.hog(
image_float, orientations=4, pixels_per_cell=(8, 8),
cells_per_block=(1, 1), visualize=True, transform_sqrt=False,
block_norm='L1')
(hog_uint8, hog_img_uint8) = feature.hog(
image_uint8, orientations=4, pixels_per_cell=(8, 8),
cells_per_block=(1, 1), visualize=True, transform_sqrt=False,
block_norm='L1')
(hog_float_norm, hog_img_float_norm) = feature.hog(
image_float, orientations=4, pixels_per_cell=(8, 8),
cells_per_block=(1, 1), visualize=True, transform_sqrt=True,
block_norm='L1')
(hog_uint8_norm, hog_img_uint8_norm) = feature.hog(
image_uint8, orientations=4, pixels_per_cell=(8, 8),
cells_per_block=(1, 1), visualize=True, transform_sqrt=True,
block_norm='L1')
# set to True to enable manual debugging with graphical output,
# must be False for automatic testing
if False:
import matplotlib.pyplot as plt
plt.figure()
plt.subplot(2, 3, 1)
plt.imshow(image_float)
plt.colorbar()
plt.title('image')
plt.subplot(2, 3, 2)
plt.imshow(hog_img_float)
plt.colorbar()
plt.title('HOG result visualisation (float img)')
plt.subplot(2, 3, 5)
plt.imshow(hog_img_uint8)
plt.colorbar()
plt.title('HOG result visualisation (uint8 img)')
plt.subplot(2, 3, 3)
plt.imshow(hog_img_float_norm)
plt.colorbar()
plt.title('HOG result (transform_sqrt) visualisation (float img)')
plt.subplot(2, 3, 6)
plt.imshow(hog_img_uint8_norm)
plt.colorbar()
plt.title('HOG result (transform_sqrt) visualisation (uint8 img)')
plt.show()
# results (features and visualisation) for float and uint8 images must
# be almost equal
assert_almost_equal(hog_float, hog_uint8)
assert_almost_equal(hog_img_float, hog_img_uint8)
# resulting features should be almost equal
# when 'transform_sqrt' is enabled
# or disabled (for current simple testing image)
assert_almost_equal(hog_float, hog_float_norm, decimal=4)
assert_almost_equal(hog_float, hog_uint8_norm, decimal=4)
# reshape resulting feature vector to matrix with 4 columns (each
# corresponding to one of 4 directions); only one direction should
# contain nonzero values (this is manually determined for testing
# image)
actual = np.max(hog_float.reshape(-1, 4), axis=0)
if rot in [0, 2]:
# image is rotated by 0 and 180 degrees
desired = [0, 0, 1, 0]
elif rot in [1, 3]:
# image is rotated by 90 and 270 degrees
desired = [1, 0, 0, 0]
else:
raise Exception('Result is not determined for this rotation.')
assert_almost_equal(actual, desired, decimal=2)
def test_hog_orientations_circle():
# scenario:
# 1) create image with blurred circle in the middle
# 2) calculate feature.hog()
# 3) verify that the resulting feature vector contains uniformly
# distributed values for all orientations, i.e. no orientation is
# lost or emphasized
# 4) repeat the scenario for other 'orientations' option
# size of testing image
width = height = 100
image = np.zeros((height, width))
rr, cc = draw.disk((int(height / 2), int(width / 2)), int(width / 3))
image[rr, cc] = 100
image = filters.gaussian(image, 2, mode='reflect')
for orientations in range(2, 15):
(hog, hog_img) = feature.hog(image, orientations=orientations,
pixels_per_cell=(8, 8),
cells_per_block=(1, 1), visualize=True,
transform_sqrt=False,
block_norm='L1')
# set to True to enable manual debugging with graphical output,
# must be False for automatic testing
if False:
import matplotlib.pyplot as plt
plt.figure()
plt.subplot(1, 2, 1)
plt.imshow(image)
plt.colorbar()
plt.title('image_float')
plt.subplot(1, 2, 2)
plt.imshow(hog_img)
plt.colorbar()
plt.title('HOG result visualisation, '
f'orientations={orientations}')
plt.show()
# reshape resulting feature vector to matrix with N columns (each
# column corresponds to one direction),
hog_matrix = hog.reshape(-1, orientations)
# compute mean values in the resulting feature vector for each
# direction, these values should be almost equal to the global mean
# value (since the image contains a circle), i.e., all directions have
# same contribution to the result
actual = np.mean(hog_matrix, axis=0)
desired = np.mean(hog_matrix)
assert_almost_equal(actual, desired, decimal=1)
def test_hog_visualization_orientation():
"""Test that the visualization produces a line with correct orientation
The hog visualization is expected to draw line segments perpendicular to
the midpoints of orientation bins. This example verifies that when
orientations=3 and the gradient is entirely in the middle bin (bisected
by the y-axis), the line segment drawn by the visualization is horizontal.
"""
width = height = 11
image = np.zeros((height, width), dtype='float')
image[height // 2:] = 1
_, hog_image = feature.hog(
image,
orientations=3,
pixels_per_cell=(width, height),
cells_per_block=(1, 1),
visualize=True,
block_norm='L1'
)
middle_index = height // 2
indices_excluding_middle = [x for x in range(height) if x != middle_index]
assert (hog_image[indices_excluding_middle, :] == 0).all()
assert (hog_image[middle_index, 1:-1] > 0).all()
def test_hog_block_normalization_incorrect_error():
img = np.eye(4)
with pytest.raises(ValueError):
feature.hog(img, block_norm='Linf')
@pytest.mark.parametrize("shape,channel_axis", [
((3, 3, 3), None),
((3, 3), -1),
((3, 3, 3, 3), -1),
])
def test_hog_incorrect_dimensions(shape, channel_axis):
img = np.zeros(shape)
with pytest.raises(ValueError):
feature.hog(img, channel_axis=channel_axis, block_norm='L1')
def test_hog_output_equivariance_deprecated_multichannel():
img = data.astronaut()
img[:, :, (1, 2)] = 0
hog_ref = feature.hog(img, channel_axis=-1, block_norm='L1')
for n in (1, 2):
hog_fact = feature.hog(np.roll(img, n, axis=2), channel_axis=-1,
block_norm='L1')
assert_almost_equal(hog_ref, hog_fact)
@pytest.mark.parametrize('channel_axis', [0, 1, -1, -2])
def test_hog_output_equivariance_channel_axis(channel_axis):
img = data.astronaut()[:64, :32]
img[:, :, (1, 2)] = 0
img = np.moveaxis(img, -1, channel_axis)
hog_ref = feature.hog(img, channel_axis=channel_axis, block_norm='L1')
for n in (1, 2):
hog_fact = feature.hog(np.roll(img, n, axis=channel_axis),
channel_axis=channel_axis, block_norm='L1')
assert_almost_equal(hog_ref, hog_fact)

View File

@@ -1,179 +0,0 @@
import numpy as np
from skimage._shared.testing import assert_equal
from skimage import data
from skimage import transform
from skimage.color import rgb2gray
from skimage.feature import (BRIEF, match_descriptors,
corner_peaks, corner_harris)
from skimage._shared import testing
def test_binary_descriptors_unequal_descriptor_sizes_error():
"""Sizes of descriptors of keypoints to be matched should be equal."""
descs1 = np.array([[True, True, False, True],
[False, True, False, True]])
descs2 = np.array([[True, False, False, True, False],
[False, True, True, True, False]])
with testing.raises(ValueError):
match_descriptors(descs1, descs2)
def test_binary_descriptors():
descs1 = np.array([[True, True, False, True, True],
[False, True, False, True, True]])
descs2 = np.array([[True, False, False, True, False],
[False, False, True, True, True]])
matches = match_descriptors(descs1, descs2)
assert_equal(matches, [[0, 0], [1, 1]])
def test_binary_descriptors_rotation_crosscheck_false():
"""Verify matched keypoints and their corresponding masks results between
image and its rotated version with the expected keypoint pairs with
cross_check disabled."""
img = data.astronaut()
img = rgb2gray(img)
tform = transform.SimilarityTransform(scale=1, rotation=0.15, translation=(0, 0))
rotated_img = transform.warp(img, tform, clip=False)
extractor = BRIEF(descriptor_size=512)
keypoints1 = corner_peaks(corner_harris(img), min_distance=5,
threshold_abs=0, threshold_rel=0.1)
extractor.extract(img, keypoints1)
descriptors1 = extractor.descriptors
keypoints2 = corner_peaks(corner_harris(rotated_img), min_distance=5,
threshold_abs=0, threshold_rel=0.1)
extractor.extract(rotated_img, keypoints2)
descriptors2 = extractor.descriptors
matches = match_descriptors(descriptors1, descriptors2, cross_check=False)
exp_matches1 = np.arange(47)
exp_matches2 = np.array([0, 2, 1, 3, 4, 5, 7, 8, 14, 9, 11, 13,
23, 15, 16, 22, 17, 19, 37, 18, 24, 27,
30, 25, 26, 32, 28, 35, 37, 42, 29, 38,
33, 40, 36, 39, 10, 36, 43, 15, 35, 41,
6, 37, 32, 24, 8])
assert_equal(matches[:, 0], exp_matches1)
assert_equal(matches[:, 1], exp_matches2)
# minkowski takes a different code path, therefore we test it explicitly
matches = match_descriptors(descriptors1, descriptors2,
metric='minkowski', cross_check=False)
assert_equal(matches[:, 0], exp_matches1)
assert_equal(matches[:, 1], exp_matches2)
# it also has an extra parameter
matches = match_descriptors(descriptors1, descriptors2,
metric='minkowski', p=4, cross_check=False)
assert_equal(matches[:, 0], exp_matches1)
assert_equal(matches[:, 1], exp_matches2)
def test_binary_descriptors_rotation_crosscheck_true():
"""Verify matched keypoints and their corresponding masks results between
image and its rotated version with the expected keypoint pairs with
cross_check enabled."""
img = data.astronaut()
img = rgb2gray(img)
tform = transform.SimilarityTransform(scale=1, rotation=0.15, translation=(0, 0))
rotated_img = transform.warp(img, tform, clip=False)
extractor = BRIEF(descriptor_size=512)
keypoints1 = corner_peaks(corner_harris(img), min_distance=5,
threshold_abs=0, threshold_rel=0.1)
extractor.extract(img, keypoints1)
descriptors1 = extractor.descriptors
keypoints2 = corner_peaks(corner_harris(rotated_img), min_distance=5,
threshold_abs=0, threshold_rel=0.1)
extractor.extract(rotated_img, keypoints2)
descriptors2 = extractor.descriptors
matches = match_descriptors(descriptors1, descriptors2, cross_check=True)
exp_matches1 = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 19, 20, 21, 22, 23,
24, 26, 27, 28, 29, 30, 31, 32, 33,
34, 38, 41, 42])
exp_matches2 = np.array([0, 2, 1, 3, 4, 5, 7, 8, 14, 9, 11, 13,
23, 15, 16, 22, 17, 19, 18, 24, 27, 30,
25, 26, 28, 35, 37, 42, 29, 38, 33,
40, 36, 43, 41, 6])
assert_equal(matches[:, 0], exp_matches1)
assert_equal(matches[:, 1], exp_matches2)
def test_max_distance():
descs1 = np.zeros((10, 128))
descs2 = np.zeros((15, 128))
descs1[0, :] = 1
matches = match_descriptors(descs1, descs2, metric='euclidean',
max_distance=0.1, cross_check=False)
assert len(matches) == 9
matches = match_descriptors(descs1, descs2, metric='euclidean',
max_distance=np.sqrt(128.1),
cross_check=False)
assert len(matches) == 10
matches = match_descriptors(descs1, descs2, metric='euclidean',
max_distance=0.1,
cross_check=True)
assert_equal(matches, [[1, 0]])
matches = match_descriptors(descs1, descs2, metric='euclidean',
max_distance=np.sqrt(128.1),
cross_check=True)
assert_equal(matches, [[1, 0]])
def test_max_ratio():
descs1 = 10 * np.arange(10)[:, None].astype(np.float32)
descs2 = 10 * np.arange(15)[:, None].astype(np.float32)
descs2[0] = 5.0
matches = match_descriptors(descs1, descs2, metric='euclidean',
max_ratio=1.0, cross_check=False)
assert_equal(len(matches), 10)
matches = match_descriptors(descs1, descs2, metric='euclidean',
max_ratio=0.6, cross_check=False)
assert_equal(len(matches), 10)
matches = match_descriptors(descs1, descs2, metric='euclidean',
max_ratio=0.5, cross_check=False)
assert_equal(len(matches), 9)
descs1[0] = 7.5
matches = match_descriptors(descs1, descs2, metric='euclidean',
max_ratio=0.5, cross_check=False)
assert_equal(len(matches), 9)
descs2 = 10 * np.arange(1)[:, None].astype(np.float32)
matches = match_descriptors(descs1, descs2, metric='euclidean',
max_ratio=1.0, cross_check=False)
assert_equal(len(matches), 10)
matches = match_descriptors(descs1, descs2, metric='euclidean',
max_ratio=0.5, cross_check=False)
assert_equal(len(matches), 10)
descs1 = 10 * np.arange(1)[:, None].astype(np.float32)
matches = match_descriptors(descs1, descs2, metric='euclidean',
max_ratio=1.0, cross_check=False)
assert_equal(len(matches), 1)
matches = match_descriptors(descs1, descs2, metric='euclidean',
max_ratio=0.5, cross_check=False)
assert_equal(len(matches), 1)

View File

@@ -1,147 +0,0 @@
import numpy as np
import pytest
from numpy.testing import assert_almost_equal, assert_equal
from skimage import data
from skimage._shared.testing import test_parallel, xfail, arch32
from skimage.feature import ORB
from skimage.util.dtype import _convert
img = data.coins()
@test_parallel()
@pytest.mark.parametrize(
'dtype', ['float32', 'float64', 'uint8', 'uint16', 'int64']
)
def test_keypoints_orb_desired_no_of_keypoints(dtype):
_img = _convert(img, dtype)
detector_extractor = ORB(n_keypoints=10, fast_n=12, fast_threshold=0.20)
detector_extractor.detect(_img)
exp_rows = np.array([141., 108., 214.56, 131., 214.272, 67.,
206., 177., 108., 141.])
exp_cols = np.array([323., 328., 282.24, 292., 281.664, 85.,
260., 284., 328.8, 267.])
exp_scales = np.array([1, 1, 1.44, 1, 1.728, 1, 1, 1, 1.2, 1])
exp_orientations = np.array([-53.97446153, 59.5055285, -96.01885186,
-149.70789506, -94.70171899, -45.76429535,
-51.49752849, 113.57081195, 63.30428063,
-79.56091118])
exp_response = np.array([1.01168357, 0.82934145, 0.67784179, 0.57176438,
0.56637459, 0.52248355, 0.43696175, 0.42992376,
0.37700486, 0.36126832])
if np.dtype(dtype) == np.float32:
assert detector_extractor.scales.dtype == np.float32
assert detector_extractor.responses.dtype == np.float32
assert detector_extractor.orientations.dtype == np.float32
else:
assert detector_extractor.scales.dtype == np.float64
assert detector_extractor.responses.dtype == np.float64
assert detector_extractor.orientations.dtype == np.float64
assert_almost_equal(exp_rows, detector_extractor.keypoints[:, 0])
assert_almost_equal(exp_cols, detector_extractor.keypoints[:, 1])
assert_almost_equal(exp_scales, detector_extractor.scales)
assert_almost_equal(exp_response, detector_extractor.responses, 5)
assert_almost_equal(exp_orientations,
np.rad2deg(detector_extractor.orientations), 4)
detector_extractor.detect_and_extract(img)
assert_almost_equal(exp_rows, detector_extractor.keypoints[:, 0])
assert_almost_equal(exp_cols, detector_extractor.keypoints[:, 1])
@pytest.mark.parametrize(
'dtype', ['float32', 'float64', 'uint8', 'uint16', 'int64']
)
def test_keypoints_orb_less_than_desired_no_of_keypoints(dtype):
_img = _convert(img, dtype)
detector_extractor = ORB(n_keypoints=15, fast_n=12,
fast_threshold=0.33, downscale=2, n_scales=2)
detector_extractor.detect(_img)
exp_rows = np.array([108., 203., 140., 65., 58.])
exp_cols = np.array([293., 267., 202., 130., 291.])
exp_scales = np.array([1., 1., 1., 1., 1.])
exp_orientations = np.array([151.93906, -56.90052, -79.46341,
-59.42996, -158.26941])
exp_response = np.array([-0.1764169, 0.2652126, -0.0324343,
0.0400902, 0.2667641])
assert_almost_equal(exp_rows, detector_extractor.keypoints[:, 0])
assert_almost_equal(exp_cols, detector_extractor.keypoints[:, 1])
assert_almost_equal(exp_scales, detector_extractor.scales)
assert_almost_equal(exp_response, detector_extractor.responses)
assert_almost_equal(exp_orientations,
np.rad2deg(detector_extractor.orientations), 3)
detector_extractor.detect_and_extract(img)
assert_almost_equal(exp_rows, detector_extractor.keypoints[:, 0])
assert_almost_equal(exp_cols, detector_extractor.keypoints[:, 1])
@xfail(condition=arch32,
reason=('Known test failure on 32-bit platforms. See links for '
'details: '
'https://github.com/scikit-image/scikit-image/issues/3091 '
'https://github.com/scikit-image/scikit-image/issues/2529'))
def test_descriptor_orb():
detector_extractor = ORB(fast_n=12, fast_threshold=0.20)
exp_descriptors = np.array([[0, 0, 0, 1, 0, 0, 0, 1, 0, 1],
[1, 1, 0, 1, 0, 0, 0, 1, 0, 1],
[1, 1, 0, 0, 1, 0, 0, 0, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 1, 0],
[0, 0, 0, 1, 0, 1, 1, 1, 1, 1],
[1, 0, 0, 1, 1, 0, 0, 0, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[1, 1, 1, 0, 1, 1, 1, 1, 0, 0],
[1, 1, 1, 1, 0, 0, 0, 1, 1, 1],
[0, 1, 1, 0, 0, 1, 1, 0, 1, 1],
[1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
[1, 0, 0, 0, 0, 1, 0, 1, 1, 1],
[1, 0, 1, 1, 1, 0, 1, 0, 1, 0],
[0, 0, 1, 1, 0, 0, 0, 0, 1, 1],
[0, 1, 1, 0, 0, 0, 1, 0, 0, 1],
[0, 1, 1, 0, 0, 0, 1, 1, 1, 1],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 1, 1, 1, 1, 0, 1, 1, 0],
[0, 0, 1, 1, 1, 0, 1, 0, 0, 1],
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0]], dtype=bool)
detector_extractor.detect(img)
detector_extractor.extract(img, detector_extractor.keypoints,
detector_extractor.scales,
detector_extractor.orientations)
assert_equal(exp_descriptors,
detector_extractor.descriptors[100:120, 10:20])
detector_extractor.detect_and_extract(img)
assert_equal(exp_descriptors,
detector_extractor.descriptors[100:120, 10:20])
keypoints_count = detector_extractor.keypoints.shape[0]
assert keypoints_count == detector_extractor.descriptors.shape[0]
assert keypoints_count == detector_extractor.orientations.shape[0]
assert keypoints_count == detector_extractor.responses.shape[0]
assert keypoints_count == detector_extractor.scales.shape[0]
def test_no_descriptors_extracted_orb():
img = np.ones((128, 128))
detector_extractor = ORB()
with pytest.raises(RuntimeError):
detector_extractor.detect_and_extract(img)
def test_img_too_small_orb():
img = data.brick()[:64,:64]
detector_extractor = ORB(downscale=2, n_scales=8)
detector_extractor.detect(img)
detector_extractor.detect_and_extract(img)

View File

@@ -1,573 +0,0 @@
import itertools
import numpy as np
import pytest
from numpy.testing import (assert_array_almost_equal, assert_array_equal,
assert_equal)
from scipy import ndimage as ndi
from skimage._shared._warnings import expected_warnings
from skimage.feature import peak
np.random.seed(21)
class TestPeakLocalMax():
def test_trivial_case(self):
trivial = np.zeros((25, 25))
peak_indices = peak.peak_local_max(trivial, min_distance=1)
assert type(peak_indices) is np.ndarray
assert peak_indices.size == 0
def test_noisy_peaks(self):
peak_locations = [(7, 7), (7, 13), (13, 7), (13, 13)]
# image with noise of amplitude 0.8 and peaks of amplitude 1
image = 0.8 * np.random.rand(20, 20)
for r, c in peak_locations:
image[r, c] = 1
peaks_detected = peak.peak_local_max(image, min_distance=5)
assert len(peaks_detected) == len(peak_locations)
for loc in peaks_detected:
assert tuple(loc) in peak_locations
def test_relative_threshold(self):
image = np.zeros((5, 5), dtype=np.uint8)
image[1, 1] = 10
image[3, 3] = 20
peaks = peak.peak_local_max(image, min_distance=1, threshold_rel=0.5)
assert len(peaks) == 1
assert_array_almost_equal(peaks, [(3, 3)])
def test_absolute_threshold(self):
image = np.zeros((5, 5), dtype=np.uint8)
image[1, 1] = 10
image[3, 3] = 20
peaks = peak.peak_local_max(image, min_distance=1, threshold_abs=10)
assert len(peaks) == 1
assert_array_almost_equal(peaks, [(3, 3)])
def test_constant_image(self):
image = np.full((20, 20), 128, dtype=np.uint8)
peaks = peak.peak_local_max(image, min_distance=1)
assert len(peaks) == 0
def test_flat_peak(self):
image = np.zeros((5, 5), dtype=np.uint8)
image[1:3, 1:3] = 10
peaks = peak.peak_local_max(image, min_distance=1)
assert len(peaks) == 4
def test_sorted_peaks(self):
image = np.zeros((5, 5), dtype=np.uint8)
image[1, 1] = 20
image[3, 3] = 10
peaks = peak.peak_local_max(image, min_distance=1)
assert peaks.tolist() == [[1, 1], [3, 3]]
image = np.zeros((3, 10))
image[1, (1, 3, 5, 7)] = (1, 2, 3, 4)
peaks = peak.peak_local_max(image, min_distance=1)
assert peaks.tolist() == [[1, 7], [1, 5], [1, 3], [1, 1]]
def test_num_peaks(self):
image = np.zeros((7, 7), dtype=np.uint8)
image[1, 1] = 10
image[1, 3] = 11
image[1, 5] = 12
image[3, 5] = 8
image[5, 3] = 7
assert len(peak.peak_local_max(image, min_distance=1,
threshold_abs=0)) == 5
peaks_limited = peak.peak_local_max(
image, min_distance=1, threshold_abs=0, num_peaks=2)
assert len(peaks_limited) == 2
assert (1, 3) in peaks_limited
assert (1, 5) in peaks_limited
peaks_limited = peak.peak_local_max(
image, min_distance=1, threshold_abs=0, num_peaks=4)
assert len(peaks_limited) == 4
assert (1, 3) in peaks_limited
assert (1, 5) in peaks_limited
assert (1, 1) in peaks_limited
assert (3, 5) in peaks_limited
def test_num_peaks_and_labels(self):
image = np.zeros((7, 7), dtype=np.uint8)
labels = np.zeros((7, 7), dtype=np.uint8) + 20
image[1, 1] = 10
image[1, 3] = 11
image[1, 5] = 12
image[3, 5] = 8
image[5, 3] = 7
peaks_limited = peak.peak_local_max(
image, min_distance=1, threshold_abs=0, labels=labels)
assert len(peaks_limited) == 5
peaks_limited = peak.peak_local_max(
image, min_distance=1, threshold_abs=0, labels=labels, num_peaks=2)
assert len(peaks_limited) == 2
def test_num_peaks_tot_vs_labels_4quadrants(self):
np.random.seed(21)
image = np.random.uniform(size=(20, 30))
i, j = np.mgrid[0:20, 0:30]
labels = 1 + (i >= 10) + (j >= 15) * 2
result = peak.peak_local_max(image, labels=labels,
min_distance=1, threshold_rel=0,
num_peaks=np.inf,
num_peaks_per_label=2)
assert len(result) == 8
result = peak.peak_local_max(image, labels=labels,
min_distance=1, threshold_rel=0,
num_peaks=np.inf,
num_peaks_per_label=1)
assert len(result) == 4
result = peak.peak_local_max(image, labels=labels,
min_distance=1, threshold_rel=0,
num_peaks=2,
num_peaks_per_label=2)
assert len(result) == 2
def test_num_peaks3D(self):
# Issue 1354: the old code only hold for 2D arrays
# and this code would die with IndexError
image = np.zeros((10, 10, 100))
image[5, 5, ::5] = np.arange(20)
peaks_limited = peak.peak_local_max(image, min_distance=1, num_peaks=2)
assert len(peaks_limited) == 2
def test_reorder_labels(self):
image = np.random.uniform(size=(40, 60))
i, j = np.mgrid[0:40, 0:60]
labels = 1 + (i >= 20) + (j >= 30) * 2
labels[labels == 4] = 5
i, j = np.mgrid[-3:4, -3:4]
footprint = (i * i + j * j <= 9)
expected = np.zeros(image.shape, float)
for imin, imax in ((0, 20), (20, 40)):
for jmin, jmax in ((0, 30), (30, 60)):
expected[imin:imax, jmin:jmax] = ndi.maximum_filter(
image[imin:imax, jmin:jmax], footprint=footprint)
expected = (expected == image)
peak_idx = peak.peak_local_max(image, labels=labels, min_distance=1,
threshold_rel=0, footprint=footprint,
exclude_border=False)
result = np.zeros_like(expected, dtype=bool)
result[tuple(peak_idx.T)] = True
assert (result == expected).all()
def test_indices_with_labels(self):
image = np.random.uniform(size=(40, 60))
i, j = np.mgrid[0:40, 0:60]
labels = 1 + (i >= 20) + (j >= 30) * 2
i, j = np.mgrid[-3:4, -3:4]
footprint = (i * i + j * j <= 9)
expected = np.zeros(image.shape, float)
for imin, imax in ((0, 20), (20, 40)):
for jmin, jmax in ((0, 30), (30, 60)):
expected[imin:imax, jmin:jmax] = ndi.maximum_filter(
image[imin:imax, jmin:jmax], footprint=footprint)
expected = np.stack(np.nonzero(expected == image), axis=-1)
expected = expected[np.argsort(image[tuple(expected.T)])[::-1]]
result = peak.peak_local_max(image, labels=labels, min_distance=1,
threshold_rel=0, footprint=footprint,
exclude_border=False)
result = result[np.argsort(image[tuple(result.T)])[::-1]]
assert (result == expected).all()
def test_ndarray_exclude_border(self):
nd_image = np.zeros((5, 5, 5))
nd_image[[1, 0, 0], [0, 1, 0], [0, 0, 1]] = 1
nd_image[3, 0, 0] = 1
nd_image[2, 2, 2] = 1
expected = np.array([[2, 2, 2]], dtype=int)
expectedNoBorder = np.array([[0, 0, 1], [2, 2, 2], [3, 0, 0]],
dtype=int)
result = peak.peak_local_max(nd_image, min_distance=2,
exclude_border=2)
assert_array_equal(result, expected)
# Check that bools work as expected
assert_array_equal(
peak.peak_local_max(nd_image, min_distance=2, exclude_border=2),
peak.peak_local_max(nd_image, min_distance=2, exclude_border=True)
)
assert_array_equal(
peak.peak_local_max(nd_image, min_distance=2, exclude_border=0),
peak.peak_local_max(nd_image, min_distance=2, exclude_border=False)
)
# Check both versions with no border
result = peak.peak_local_max(nd_image, min_distance=2,
exclude_border=0)
assert_array_equal(result, expectedNoBorder)
peak_idx = peak.peak_local_max(nd_image, exclude_border=False)
result = np.zeros_like(nd_image, dtype=bool)
result[tuple(peak_idx.T)] = True
assert_array_equal(result, nd_image.astype(bool))
def test_empty(self):
image = np.zeros((10, 20))
labels = np.zeros((10, 20), int)
result = peak.peak_local_max(image, labels=labels,
footprint=np.ones((3, 3), bool),
min_distance=1, threshold_rel=0,
exclude_border=False)
assert result.shape == (0, image.ndim)
def test_empty_non2d_indices(self):
image = np.zeros((10, 10, 10))
result = peak.peak_local_max(image,
footprint=np.ones((3, 3, 3), bool),
min_distance=1, threshold_rel=0,
exclude_border=False)
assert result.shape == (0, image.ndim)
def test_one_point(self):
image = np.zeros((10, 20))
labels = np.zeros((10, 20), int)
image[5, 5] = 1
labels[5, 5] = 1
peak_idx = peak.peak_local_max(image, labels=labels,
footprint=np.ones((3, 3), bool),
min_distance=1, threshold_rel=0,
exclude_border=False)
result = np.zeros_like(image, dtype=bool)
result[tuple(peak_idx.T)] = True
assert np.all(result == (labels == 1))
def test_adjacent_and_same(self):
image = np.zeros((10, 20))
labels = np.zeros((10, 20), int)
image[5, 5:6] = 1
labels[5, 5:6] = 1
expected = np.stack(np.where(labels == 1), axis=-1)
result = peak.peak_local_max(image, labels=labels,
footprint=np.ones((3, 3), bool),
min_distance=1, threshold_rel=0,
exclude_border=False)
assert_array_equal(result, expected)
def test_adjacent_and_different(self):
image = np.zeros((10, 20))
labels = np.zeros((10, 20), int)
image[5, 5] = 1
image[5, 6] = .5
labels[5, 5:6] = 1
expected = np.stack(np.where(image == 1), axis=-1)
result = peak.peak_local_max(image, labels=labels,
footprint=np.ones((3, 3), bool),
min_distance=1, threshold_rel=0,
exclude_border=False)
assert_array_equal(result, expected)
result = peak.peak_local_max(image, labels=labels,
min_distance=1, threshold_rel=0,
exclude_border=False)
assert_array_equal(result, expected)
def test_not_adjacent_and_different(self):
image = np.zeros((10, 20))
labels = np.zeros((10, 20), int)
image[5, 5] = 1
image[5, 8] = .5
labels[image > 0] = 1
expected = np.stack(np.where(labels == 1), axis=-1)
result = peak.peak_local_max(image, labels=labels,
footprint=np.ones((3, 3), bool),
min_distance=1, threshold_rel=0,
exclude_border=False)
assert_array_equal(result, expected)
def test_two_objects(self):
image = np.zeros((10, 20))
labels = np.zeros((10, 20), int)
image[5, 5] = 1
image[5, 15] = .5
labels[5, 5] = 1
labels[5, 15] = 2
expected = np.stack(np.where(labels > 0), axis=-1)
result = peak.peak_local_max(image, labels=labels,
footprint=np.ones((3, 3), bool),
min_distance=1, threshold_rel=0,
exclude_border=False)
assert_array_equal(result, expected)
def test_adjacent_different_objects(self):
image = np.zeros((10, 20))
labels = np.zeros((10, 20), int)
image[5, 5] = 1
image[5, 6] = .5
labels[5, 5] = 1
labels[5, 6] = 2
expected = np.stack(np.where(labels > 0), axis=-1)
result = peak.peak_local_max(image, labels=labels,
footprint=np.ones((3, 3), bool),
min_distance=1, threshold_rel=0,
exclude_border=False)
assert_array_equal(result, expected)
def test_four_quadrants(self):
image = np.random.uniform(size=(20, 30))
i, j = np.mgrid[0:20, 0:30]
labels = 1 + (i >= 10) + (j >= 15) * 2
i, j = np.mgrid[-3:4, -3:4]
footprint = (i * i + j * j <= 9)
expected = np.zeros(image.shape, float)
for imin, imax in ((0, 10), (10, 20)):
for jmin, jmax in ((0, 15), (15, 30)):
expected[imin:imax, jmin:jmax] = ndi.maximum_filter(
image[imin:imax, jmin:jmax], footprint=footprint)
expected = (expected == image)
peak_idx = peak.peak_local_max(image, labels=labels,
footprint=footprint,
min_distance=1,
threshold_rel=0,
exclude_border=False)
result = np.zeros_like(image, dtype=bool)
result[tuple(peak_idx.T)] = True
assert np.all(result == expected)
def test_disk(self):
'''regression test of img-1194, footprint = [1]
Test peak.peak_local_max when every point is a local maximum
'''
image = np.random.uniform(size=(10, 20))
footprint = np.array([[1]])
peak_idx = peak.peak_local_max(image, labels=np.ones((10, 20), int),
footprint=footprint,
min_distance=1, threshold_rel=0,
threshold_abs=-1,
exclude_border=False)
result = np.zeros_like(image, dtype=bool)
result[tuple(peak_idx.T)] = True
assert np.all(result)
peak_idx = peak.peak_local_max(image, footprint=footprint,
threshold_abs=-1,
exclude_border=False)
result = np.zeros_like(image, dtype=bool)
result[tuple(peak_idx.T)] = True
assert np.all(result)
def test_3D(self):
image = np.zeros((30, 30, 30))
image[15, 15, 15] = 1
image[5, 5, 5] = 1
assert_array_equal(
peak.peak_local_max(image, min_distance=10, threshold_rel=0),
[[15, 15, 15]])
assert_array_equal(
peak.peak_local_max(image, min_distance=6, threshold_rel=0),
[[15, 15, 15]])
assert sorted(
peak.peak_local_max(image, min_distance=10, threshold_rel=0,
exclude_border=False).tolist()) == \
[[5, 5, 5], [15, 15, 15]]
assert sorted(peak.peak_local_max(image, min_distance=5,
threshold_rel=0).tolist()) == \
[[5, 5, 5], [15, 15, 15]]
def test_4D(self):
image = np.zeros((30, 30, 30, 30))
image[15, 15, 15, 15] = 1
image[5, 5, 5, 5] = 1
assert_array_equal(
peak.peak_local_max(image, min_distance=10, threshold_rel=0),
[[15, 15, 15, 15]])
assert_array_equal(
peak.peak_local_max(image, min_distance=6, threshold_rel=0),
[[15, 15, 15, 15]])
assert sorted(
peak.peak_local_max(image, min_distance=10, threshold_rel=0,
exclude_border=False).tolist()
) == [[5, 5, 5, 5], [15, 15, 15, 15]]
assert sorted(peak.peak_local_max(image, min_distance=5,
threshold_rel=0).tolist()) == \
[[5, 5, 5, 5], [15, 15, 15, 15]]
def test_threshold_rel_default(self):
image = np.ones((5, 5))
image[2, 2] = 1
assert len(peak.peak_local_max(image)) == 0
image[2, 2] = 2
assert_array_equal(peak.peak_local_max(image), [[2, 2]])
image[2, 2] = 0
with expected_warnings(["When min_distance < 1"]):
assert len(peak.peak_local_max(image,
min_distance=0)) == image.size - 1
def test_peak_at_border(self):
image = np.full((10, 10), -2)
image[2, 4] = -1
image[3, 0] = -1
peaks = peak.peak_local_max(image, min_distance=3)
assert peaks.size == 0
peaks = peak.peak_local_max(image, min_distance=3, exclude_border=0)
assert len(peaks) == 2
assert [2, 4] in peaks
assert [3, 0] in peaks
@pytest.mark.parametrize(
["indices"],
[[indices] for indices in itertools.product(range(5), range(5))],
)
def test_exclude_border(indices):
image = np.zeros((5, 5))
image[indices] = 1
# exclude_border = False, means it will always be found.
assert len(peak.peak_local_max(image, exclude_border=False)) == 1
# exclude_border = 0, means it will always be found.
assert len(peak.peak_local_max(image, exclude_border=0)) == 1
# exclude_border = True, min_distance=1 means it will be found unless it's
# on the edge.
if indices[0] in (0, 4) or indices[1] in (0, 4):
expected_peaks = 0
else:
expected_peaks = 1
assert len(peak.peak_local_max(
image, min_distance=1, exclude_border=True)) == expected_peaks
# exclude_border = (1, 0) means it will be found unless it's on the edge of
# the first dimension.
if indices[0] in (0, 4):
expected_peaks = 0
else:
expected_peaks = 1
assert len(peak.peak_local_max(
image, exclude_border=(1, 0))) == expected_peaks
# exclude_border = (0, 1) means it will be found unless it's on the edge of
# the second dimension.
if indices[1] in (0, 4):
expected_peaks = 0
else:
expected_peaks = 1
assert len(peak.peak_local_max(
image, exclude_border=(0, 1))) == expected_peaks
def test_exclude_border_errors():
image = np.zeros((5, 5))
# exclude_border doesn't have the right cardinality.
with pytest.raises(ValueError):
assert peak.peak_local_max(image, exclude_border=(1,))
# exclude_border doesn't have the right type
with pytest.raises(TypeError):
assert peak.peak_local_max(image, exclude_border=1.0)
# exclude_border is a tuple of the right cardinality but contains
# non-integer values.
with pytest.raises(ValueError):
assert peak.peak_local_max(image, exclude_border=(1, 'a'))
# exclude_border is a tuple of the right cardinality but contains a
# negative value.
with pytest.raises(ValueError):
assert peak.peak_local_max(image, exclude_border=(1, -1))
# exclude_border is a negative value.
with pytest.raises(ValueError):
assert peak.peak_local_max(image, exclude_border=-1)
def test_input_values_with_labels():
# Issue #5235: input values may be modified when labels are used
img = np.random.rand(128, 128)
labels = np.zeros((128, 128), int)
labels[10:20, 10:20] = 1
labels[12:16, 12:16] = 0
img_before = img.copy()
_ = peak.peak_local_max(img, labels=labels)
assert_array_equal(img, img_before)
class TestProminentPeaks():
def test_isolated_peaks(self):
image = np.zeros((15, 15))
x0, y0, i0 = (12, 8, 1)
x1, y1, i1 = (2, 2, 1)
x2, y2, i2 = (5, 13, 1)
image[y0, x0] = i0
image[y1, x1] = i1
image[y2, x2] = i2
out = peak._prominent_peaks(image)
assert len(out[0]) == 3
for i, x, y in zip(out[0], out[1], out[2]):
assert i in (i0, i1, i2)
assert x in (x0, x1, x2)
assert y in (y0, y1, y2)
def test_threshold(self):
image = np.zeros((15, 15))
x0, y0, i0 = (12, 8, 10)
x1, y1, i1 = (2, 2, 8)
x2, y2, i2 = (5, 13, 10)
image[y0, x0] = i0
image[y1, x1] = i1
image[y2, x2] = i2
out = peak._prominent_peaks(image, threshold=None)
assert len(out[0]) == 3
for i, x, y in zip(out[0], out[1], out[2]):
assert i in (i0, i1, i2)
assert x in (x0, x1, x2)
out = peak._prominent_peaks(image, threshold=9)
assert len(out[0]) == 2
for i, x, y in zip(out[0], out[1], out[2]):
assert i in (i0, i2)
assert x in (x0, x2)
assert y in (y0, y2)
def test_peaks_in_contact(self):
image = np.zeros((15, 15))
x0, y0, i0 = (8, 8, 1)
x1, y1, i1 = (7, 7, 1) # prominent peak
x2, y2, i2 = (6, 6, 1)
image[y0, x0] = i0
image[y1, x1] = i1
image[y2, x2] = i2
out = peak._prominent_peaks(image, min_xdistance=3,
min_ydistance=3,)
assert_equal(out[0], np.array((i1,)))
assert_equal(out[1], np.array((x1,)))
assert_equal(out[2], np.array((y1,)))
def test_input_labels_unmodified(self):
image = np.zeros((10, 20))
labels = np.zeros((10, 20), int)
image[5, 5] = 1
labels[5, 5] = 3
labelsin = labels.copy()
peak.peak_local_max(image, labels=labels,
footprint=np.ones((3, 3), bool),
min_distance=1, threshold_rel=0,
exclude_border=False)
assert np.all(labels == labelsin)
def test_many_objects(self):
mask = np.zeros([500, 500], dtype=bool)
x, y = np.indices((500, 500))
x_c = x // 20 * 20 + 10
y_c = y // 20 * 20 + 10
mask[(x - x_c) ** 2 + (y - y_c) ** 2 < 8 ** 2] = True
labels, num_objs = ndi.label(mask)
dist = ndi.distance_transform_edt(mask)
local_max = peak.peak_local_max(dist, min_distance=20,
exclude_border=False, labels=labels)
assert len(local_max) == 625

View File

@@ -1,131 +0,0 @@
import numpy as np
import pytest
from numpy.testing import assert_almost_equal, assert_equal
from skimage import data
from skimage._shared.testing import test_parallel
from skimage.feature import SIFT
from skimage.util.dtype import _convert
img = data.coins()
@test_parallel()
@pytest.mark.parametrize(
'dtype', ['float32', 'float64', 'uint8', 'uint16', 'int64']
)
def test_keypoints_sift(dtype):
_img = _convert(img, dtype)
detector_extractor = SIFT()
detector_extractor.detect_and_extract(_img)
exp_keypoint_rows = np.array([18, 18, 19, 22, 26, 26, 30, 31, 31, 32])
exp_keypoint_cols = np.array([331, 331, 325, 330, 310, 330, 205, 323, 149,
338])
exp_octaves = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
exp_position_rows = np.array([17.81909936, 17.81909936, 19.05454661,
21.85933727, 25.54800708, 26.25710504,
29.90826307, 30.78713806, 30.87953572,
31.72557969])
exp_position_cols = np.array([331.49693187, 331.49693187, 325.24476016,
330.44616424, 310.33932904, 330.46155224,
204.74535177, 322.84100812, 149.43192282,
337.89643013])
exp_orientations = np.array([0.26391655, 0.26391655, 0.39134262,
1.77063053, 0.98637565, 1.37997279, 0.4919992,
1.48615988, 0.33753212, 1.64859617])
exp_scales = np.array([2, 2, 1, 3, 3, 1, 2, 1, 1, 1])
exp_sigmas = np.array([1.35160379, 1.35160379, 0.94551567, 1.52377498,
1.55173233, 0.93973722, 1.37594124, 1.06663786,
1.04827034, 1.0378916])
exp_scalespace_sigmas = np.array([[0.8, 1.00793684, 1.26992084, 1.6,
2.01587368, 2.53984168],
[1.6, 2.01587368, 2.53984168, 3.2,
4.03174736, 5.07968337],
[3.2, 4.03174736, 5.07968337, 6.4,
8.06349472, 10.15936673],
[6.4, 8.06349472, 10.15936673, 12.8,
16.12698944, 20.31873347],
[12.8, 16.12698944, 20.31873347, 25.6,
32.25397888, 40.63746693],
[25.6, 32.25397888, 40.63746693, 51.2,
64.50795775, 81.27493386]])
assert_almost_equal(exp_keypoint_rows,
detector_extractor.keypoints[:10, 0])
assert_almost_equal(exp_keypoint_cols,
detector_extractor.keypoints[:10, 1])
assert_almost_equal(exp_octaves,
detector_extractor.octaves[:10])
assert_almost_equal(exp_position_rows,
detector_extractor.positions[:10, 0], decimal=4)
assert_almost_equal(exp_position_cols,
detector_extractor.positions[:10, 1], decimal=4)
assert_almost_equal(exp_orientations,
detector_extractor.orientations[:10], decimal=4)
assert_almost_equal(exp_scales,
detector_extractor.scales[:10])
assert_almost_equal(exp_sigmas,
detector_extractor.sigmas[:10], decimal=4)
assert_almost_equal(exp_scalespace_sigmas,
detector_extractor.scalespace_sigmas, decimal=4)
detector_extractor2 = SIFT()
detector_extractor2.detect(img)
detector_extractor2.extract(img)
assert_almost_equal(detector_extractor.keypoints[:10, 0],
detector_extractor2.keypoints[:10, 0])
assert_almost_equal(detector_extractor.keypoints[:10, 0],
detector_extractor2.keypoints[:10, 0])
def test_descriptor_sift():
detector_extractor = SIFT(n_hist=2, n_ori=4)
exp_descriptors = np.array([[173, 30, 55, 32, 173, 16, 45, 82, 173, 154,
170, 173, 173, 169, 65, 110],
[173, 30, 55, 32, 173, 16, 45, 82, 173, 154,
170, 173, 173, 169, 65, 110],
[189, 52, 18, 18, 189, 11, 21, 55, 189, 75,
173, 91, 189, 65, 189, 162],
[172, 156, 185, 66, 92, 76, 78, 185, 185, 87,
88, 82, 98, 56, 96, 185],
[216, 19, 40, 9, 196, 7, 57, 36, 216, 56, 158,
29, 216, 42, 144, 154],
[169, 120, 169, 91, 129, 108, 169, 67, 169,
142, 111, 95, 169, 120, 69, 41],
[199, 10, 138, 44, 178, 11, 161, 34, 199, 113,
73, 64, 199, 82, 31, 178],
[154, 56, 154, 49, 144, 154, 154, 78, 154, 51,
154, 83, 154, 154, 154, 72],
[230, 46, 47, 21, 230, 15, 65, 95, 230, 52, 72,
51, 230, 19, 59, 130],
[155, 117, 154, 102, 155, 155, 90, 110, 145,
127, 155, 50, 57, 155, 155, 70]],
dtype=np.uint8
)
detector_extractor.detect_and_extract(img)
assert_equal(exp_descriptors, detector_extractor.descriptors[:10])
keypoints_count = detector_extractor.keypoints.shape[0]
assert keypoints_count == detector_extractor.descriptors.shape[0]
assert keypoints_count == detector_extractor.orientations.shape[0]
assert keypoints_count == detector_extractor.octaves.shape[0]
assert keypoints_count == detector_extractor.positions.shape[0]
assert keypoints_count == detector_extractor.scales.shape[0]
assert keypoints_count == detector_extractor.scales.shape[0]
def test_no_descriptors_extracted_sift():
img = np.ones((128, 128))
detector_extractor = SIFT()
with pytest.raises(RuntimeError):
detector_extractor.detect_and_extract(img)

View File

@@ -1,189 +0,0 @@
import numpy as np
from skimage._shared.testing import assert_almost_equal, assert_equal
from skimage import data, img_as_float
from skimage.morphology import diamond
from skimage.feature import match_template, peak_local_max
from skimage._shared import testing
@testing.parametrize('dtype', [np.float32, np.float64])
def test_template(dtype):
size = 100
# Float prefactors ensure that image range is between 0 and 1
image = np.full((400, 400), 0.5, dtype=dtype)
target = 0.1 * (np.tri(size) + np.tri(size)[::-1])
target = target.astype(dtype, copy=False)
target_positions = [(50, 50), (200, 200)]
for x, y in target_positions:
image[x:x + size, y:y + size] = target
np.random.seed(1)
image += 0.1 * np.random.uniform(size=(400, 400)).astype(dtype, copy=False)
result = match_template(image, target)
assert result.dtype == dtype
delta = 5
positions = peak_local_max(result, min_distance=delta)
if len(positions) > 2:
# Keep the two maximum peaks.
intensities = result[tuple(positions.T)]
i_maxsort = np.argsort(intensities)[::-1]
positions = positions[i_maxsort][:2]
# Sort so that order matches `target_positions`.
positions = positions[np.argsort(positions[:, 0])]
for xy_target, xy in zip(target_positions, positions):
assert_almost_equal(xy, xy_target)
def test_normalization():
"""Test that `match_template` gives the correct normalization.
Normalization gives 1 for a perfect match and -1 for an inverted-match.
This test adds positive and negative squares to a zero-array and matches
the array with a positive template.
"""
n = 5
N = 20
ipos, jpos = (2, 3)
ineg, jneg = (12, 11)
image = np.full((N, N), 0.5)
image[ipos:ipos + n, jpos:jpos + n] = 1
image[ineg:ineg + n, jneg:jneg + n] = 0
# white square with a black border
template = np.zeros((n + 2, n + 2))
template[1:1 + n, 1:1 + n] = 1
result = match_template(image, template)
# get the max and min results.
sorted_result = np.argsort(result.flat)
iflat_min = sorted_result[0]
iflat_max = sorted_result[-1]
min_result = np.unravel_index(iflat_min, result.shape)
max_result = np.unravel_index(iflat_max, result.shape)
# shift result by 1 because of template border
assert np.all((np.array(min_result) + 1) == (ineg, jneg))
assert np.all((np.array(max_result) + 1) == (ipos, jpos))
assert np.allclose(result.flat[iflat_min], -1)
assert np.allclose(result.flat[iflat_max], 1)
def test_no_nans():
"""Test that `match_template` doesn't return NaN values.
When image values are only slightly different, floating-point errors can
cause a subtraction inside of a square root to go negative (without an
explicit check that was added to `match_template`).
"""
np.random.seed(1)
image = 0.5 + 1e-9 * np.random.normal(size=(20, 20))
template = np.ones((6, 6))
template[:3, :] = 0
result = match_template(image, template)
assert not np.any(np.isnan(result))
def test_switched_arguments():
image = np.ones((5, 5))
template = np.ones((3, 3))
with testing.raises(ValueError):
match_template(template, image)
def test_pad_input():
"""Test `match_template` when `pad_input=True`.
This test places two full templates (one with values lower than the image
mean, the other higher) and two half templates, which are on the edges of
the image. The two full templates should score the top (positive and
negative) matches and the centers of the half templates should score 2nd.
"""
# Float prefactors ensure that image range is between 0 and 1
template = 0.5 * diamond(2)
image = 0.5 * np.ones((9, 19))
mid = slice(2, 7)
image[mid, :3] -= template[:, -3:] # half min template centered at 0
image[mid, 4:9] += template # full max template centered at 6
image[mid, -9:-4] -= template # full min template centered at 12
image[mid, -3:] += template[:, :3] # half max template centered at 18
result = match_template(image, template, pad_input=True,
constant_values=image.mean())
# get the max and min results.
sorted_result = np.argsort(result.flat)
i, j = np.unravel_index(sorted_result[:2], result.shape)
assert_equal(j, (12, 0))
i, j = np.unravel_index(sorted_result[-2:], result.shape)
assert_equal(j, (18, 6))
def test_3d():
np.random.seed(1)
template = np.random.rand(3, 3, 3)
image = np.zeros((12, 12, 12))
image[3:6, 5:8, 4:7] = template
result = match_template(image, template)
assert_equal(result.shape, (10, 10, 10))
assert_equal(np.unravel_index(result.argmax(), result.shape), (3, 5, 4))
def test_3d_pad_input():
np.random.seed(1)
template = np.random.rand(3, 3, 3)
image = np.zeros((12, 12, 12))
image[3:6, 5:8, 4:7] = template
result = match_template(image, template, pad_input=True)
assert_equal(result.shape, (12, 12, 12))
assert_equal(np.unravel_index(result.argmax(), result.shape), (4, 6, 5))
def test_padding_reflect():
template = diamond(2)
image = np.zeros((10, 10))
image[2:7, :3] = template[:, -3:]
result = match_template(image, template, pad_input=True,
mode='reflect')
assert_equal(np.unravel_index(result.argmax(), result.shape), (4, 0))
def test_wrong_input():
image = np.ones((5, 5, 1))
template = np.ones((3, 3))
with testing.raises(ValueError):
match_template(template, image)
image = np.ones((5, 5))
template = np.ones((3, 3, 2))
with testing.raises(ValueError):
match_template(template, image)
image = np.ones((5, 5, 3, 3))
template = np.ones((3, 3, 2))
with testing.raises(ValueError):
match_template(template, image)
def test_bounding_values():
image = img_as_float(data.page())
template = np.zeros((3, 3))
template[1, 1] = 1
result = match_template(image, template)
print(result.max())
assert result.max() < 1 + 1e-7
assert result.min() > -1 - 1e-7

View File

@@ -1,318 +0,0 @@
import numpy as np
import pytest
from skimage._shared.testing import expected_warnings, test_parallel
from skimage.feature import (graycomatrix, graycoprops,
local_binary_pattern, multiblock_lbp)
from skimage.transform import integral_image
class TestGLCM():
def setup_method(self):
self.image = np.array([[0, 0, 1, 1],
[0, 0, 1, 1],
[0, 2, 2, 2],
[2, 2, 3, 3]], dtype=np.uint8)
@test_parallel()
def test_output_angles(self):
result = graycomatrix(
self.image, [1], [0, np.pi / 4, np.pi / 2, 3 * np.pi / 4], 4
)
assert result.shape == (4, 4, 1, 4)
expected1 = np.array([[2, 2, 1, 0],
[0, 2, 0, 0],
[0, 0, 3, 1],
[0, 0, 0, 1]], dtype=np.uint32)
np.testing.assert_array_equal(result[:, :, 0, 0], expected1)
expected2 = np.array([[1, 1, 3, 0],
[0, 1, 1, 0],
[0, 0, 0, 2],
[0, 0, 0, 0]], dtype=np.uint32)
np.testing.assert_array_equal(result[:, :, 0, 1], expected2)
expected3 = np.array([[3, 0, 2, 0],
[0, 2, 2, 0],
[0, 0, 1, 2],
[0, 0, 0, 0]], dtype=np.uint32)
np.testing.assert_array_equal(result[:, :, 0, 2], expected3)
expected4 = np.array([[2, 0, 0, 0],
[1, 1, 2, 0],
[0, 0, 2, 1],
[0, 0, 0, 0]], dtype=np.uint32)
np.testing.assert_array_equal(result[:, :, 0, 3], expected4)
def test_output_symmetric_1(self):
result = graycomatrix(self.image, [1], [np.pi / 2], 4,
symmetric=True)
assert result.shape == (4, 4, 1, 1)
expected = np.array([[6, 0, 2, 0],
[0, 4, 2, 0],
[2, 2, 2, 2],
[0, 0, 2, 0]], dtype=np.uint32)
np.testing.assert_array_equal(result[:, :, 0, 0], expected)
def test_error_raise_float(self):
for dtype in [
float, np.double, np.float16, np.float32, np.float64
]:
with pytest.raises(ValueError):
graycomatrix(self.image.astype(dtype), [1], [np.pi], 4)
def test_error_raise_int_types(self):
for dtype in [
np.int16, np.int32, np.int64, np.uint16, np.uint32, np.uint64
]:
with pytest.raises(ValueError):
graycomatrix(self.image.astype(dtype), [1], [np.pi])
def test_error_raise_negative(self):
with pytest.raises(ValueError):
graycomatrix(self.image.astype(np.int16) - 1, [1], [np.pi], 4)
def test_error_raise_levels_smaller_max(self):
with pytest.raises(ValueError):
graycomatrix(self.image - 1, [1], [np.pi], 3)
def test_image_data_types(self):
for dtype in [
np.uint16, np.uint32, np.uint64, np.int16, np.int32, np.int64
]:
img = self.image.astype(dtype)
result = graycomatrix(img, [1], [np.pi / 2], 4,
symmetric=True)
assert result.shape == (4, 4, 1, 1)
expected = np.array([[6, 0, 2, 0],
[0, 4, 2, 0],
[2, 2, 2, 2],
[0, 0, 2, 0]], dtype=np.uint32)
np.testing.assert_array_equal(result[:, :, 0, 0], expected)
return
def test_output_distance(self):
im = np.array([[0, 0, 0, 0],
[1, 0, 0, 1],
[2, 0, 0, 2],
[3, 0, 0, 3]], dtype=np.uint8)
result = graycomatrix(im, [3], [0], 4, symmetric=False)
expected = np.array([[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]], dtype=np.uint32)
np.testing.assert_array_equal(result[:, :, 0, 0], expected)
def test_output_combo(self):
im = np.array([[0],
[1],
[2],
[3]], dtype=np.uint8)
result = graycomatrix(im, [1, 2], [0, np.pi / 2], 4)
assert result.shape == (4, 4, 2, 2)
z = np.zeros((4, 4), dtype=np.uint32)
e1 = np.array([[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1],
[0, 0, 0, 0]], dtype=np.uint32)
e2 = np.array([[0, 0, 1, 0],
[0, 0, 0, 1],
[0, 0, 0, 0],
[0, 0, 0, 0]], dtype=np.uint32)
np.testing.assert_array_equal(result[:, :, 0, 0], z)
np.testing.assert_array_equal(result[:, :, 1, 0], z)
np.testing.assert_array_equal(result[:, :, 0, 1], e1)
np.testing.assert_array_equal(result[:, :, 1, 1], e2)
def test_output_empty(self):
result = graycomatrix(self.image, [10], [0], 4)
np.testing.assert_array_equal(result[:, :, 0, 0],
np.zeros((4, 4), dtype=np.uint32))
result = graycomatrix(self.image, [10], [0], 4, normed=True)
np.testing.assert_array_equal(result[:, :, 0, 0],
np.zeros((4, 4), dtype=np.uint32))
def test_normed_symmetric(self):
result = graycomatrix(self.image, [1, 2, 3],
[0, np.pi / 2, np.pi], 4,
normed=True, symmetric=True)
for d in range(result.shape[2]):
for a in range(result.shape[3]):
np.testing.assert_almost_equal(result[:, :, d, a].sum(),
1.0)
np.testing.assert_array_equal(result[:, :, d, a],
result[:, :, d, a].transpose())
def test_contrast(self):
result = graycomatrix(self.image, [1, 2], [0], 4,
normed=True, symmetric=True)
result = np.round(result, 3)
contrast = graycoprops(result, 'contrast')
np.testing.assert_almost_equal(contrast[0, 0], 0.585, decimal=3)
def test_dissimilarity(self):
result = graycomatrix(self.image, [1], [0, np.pi / 2], 4,
normed=True, symmetric=True)
result = np.round(result, 3)
dissimilarity = graycoprops(result, 'dissimilarity')
np.testing.assert_almost_equal(dissimilarity[0, 0], 0.418, decimal=3)
def test_dissimilarity_2(self):
result = graycomatrix(self.image, [1, 3], [np.pi / 2], 4,
normed=True, symmetric=True)
result = np.round(result, 3)
dissimilarity = graycoprops(result, 'dissimilarity')[0, 0]
np.testing.assert_almost_equal(dissimilarity, 0.665, decimal=3)
def test_non_normalized_glcm(self):
img = (np.random.random((100, 100)) * 8).astype(np.uint8)
p = graycomatrix(img, [1, 2, 4, 5], [0, 0.25, 1, 1.5], levels=8)
np.testing.assert_(np.max(graycoprops(p, 'correlation')) < 1.0)
def test_invalid_property(self):
result = graycomatrix(self.image, [1], [0], 4)
with pytest.raises(ValueError):
graycoprops(result, 'ABC')
def test_homogeneity(self):
result = graycomatrix(self.image, [1], [0, 6], 4, normed=True,
symmetric=True)
homogeneity = graycoprops(result, 'homogeneity')[0, 0]
np.testing.assert_almost_equal(homogeneity, 0.80833333)
def test_energy(self):
result = graycomatrix(self.image, [1], [0, 4], 4, normed=True,
symmetric=True)
energy = graycoprops(result, 'energy')[0, 0]
np.testing.assert_almost_equal(energy, 0.38188131)
def test_correlation(self):
result = graycomatrix(self.image, [1, 2], [0], 4, normed=True,
symmetric=True)
energy = graycoprops(result, 'correlation')
np.testing.assert_almost_equal(energy[0, 0], 0.71953255)
np.testing.assert_almost_equal(energy[1, 0], 0.41176470)
def test_uniform_properties(self):
im = np.ones((4, 4), dtype=np.uint8)
result = graycomatrix(im, [1, 2, 8], [0, np.pi / 2], 4, normed=True,
symmetric=True)
for prop in ['contrast', 'dissimilarity', 'homogeneity',
'energy', 'correlation', 'ASM']:
graycoprops(result, prop)
class TestLBP():
def setup_method(self):
self.image = np.array([[255, 6, 255, 0, 141, 0],
[ 48, 250, 204, 166, 223, 63],
[ 8, 0, 159, 50, 255, 30],
[167, 255, 63, 40, 128, 255],
[ 0, 255, 30, 34, 255, 24],
[146, 241, 255, 0, 189, 126]],
dtype=np.uint8)
@test_parallel()
def test_default(self):
lbp = local_binary_pattern(self.image, 8, 1, 'default')
ref = np.array([[ 0, 251, 0, 255, 96, 255],
[143, 0, 20, 153, 64, 56],
[238, 255, 12, 191, 0, 252],
[129, 64., 62, 159, 199, 0],
[255, 4, 255, 175, 0, 254],
[ 3, 5, 0, 255, 4, 24]])
np.testing.assert_array_equal(lbp, ref)
def test_ror(self):
lbp = local_binary_pattern(self.image, 8, 1, 'ror')
ref = np.array([[ 0, 127, 0, 255, 3, 255],
[ 31, 0, 5, 51, 1, 7],
[119, 255, 3, 127, 0, 63],
[ 3, 1, 31, 63, 31, 0],
[255, 1, 255, 95, 0, 127],
[ 3, 5, 0, 255, 1, 3]])
np.testing.assert_array_equal(lbp, ref)
@pytest.mark.parametrize('dtype', [np.float16, np.float32, np.float64])
def test_float_warning(self, dtype):
image = self.image.astype(dtype)
msg = "Applying `local_binary_pattern` to floating-point images"
with expected_warnings([msg]):
lbp = local_binary_pattern(image, 8, 1, 'ror')
ref = np.array([[ 0, 127, 0, 255, 3, 255],
[ 31, 0, 5, 51, 1, 7],
[119, 255, 3, 127, 0, 63],
[ 3, 1, 31, 63, 31, 0],
[255, 1, 255, 95, 0, 127],
[ 3, 5, 0, 255, 1, 3]])
np.testing.assert_array_equal(lbp, ref)
def test_uniform(self):
lbp = local_binary_pattern(self.image, 8, 1, 'uniform')
ref = np.array([[0, 7, 0, 8, 2, 8],
[5, 0, 9, 9, 1, 3],
[9, 8, 2, 7, 0, 6],
[2, 1, 5, 6, 5, 0],
[8, 1, 8, 9, 0, 7],
[2, 9, 0, 8, 1, 2]])
np.testing.assert_array_equal(lbp, ref)
def test_var(self):
# Test idea: mean of variance is estimate of overall variance.
# Fix random seed for test stability.
np.random.seed(13141516)
# Create random image with known variance.
image = np.random.rand(500, 500)
target_std = 0.3
image = image / image.std() * target_std
# Use P=4 to avoid interpolation effects
P, R = 4, 1
msg = "Applying `local_binary_pattern` to floating-point images"
with expected_warnings([msg]):
lbp = local_binary_pattern(image, P, R, 'var')
# Take central part to avoid border effect.
lbp = lbp[5:-5, 5:-5]
# The LBP variance is biased (ddof=0), correct for that.
expected = target_std**2 * (P-1)/P
np.testing.assert_almost_equal(lbp.mean(), expected, 4)
def test_nri_uniform(self):
lbp = local_binary_pattern(self.image, 8, 1, 'nri_uniform')
ref = np.array([[ 0, 54, 0, 57, 12, 57],
[34, 0, 58, 58, 3, 22],
[58, 57, 15, 50, 0, 47],
[10, 3, 40, 42, 35, 0],
[57, 7, 57, 58, 0, 56],
[ 9, 58, 0, 57, 7, 14]])
np.testing.assert_array_almost_equal(lbp, ref)
class TestMBLBP():
def test_single_mblbp(self):
# Create dummy matrix where first and fifth rectangles have greater
# value than the central one. Therefore, the following bits
# should be 1.
test_img = np.zeros((9, 9), dtype='uint8')
test_img[3:6, 3:6] = 1
test_img[:3, :3] = 255
test_img[6:, 6:] = 255
# MB-LBP is filled in reverse order. So the first and fifth bits from
# the end should be filled.
correct_answer = 0b10001000
int_img = integral_image(test_img)
lbp_code = multiblock_lbp(int_img, 0, 0, 3, 3)
np.testing.assert_equal(lbp_code, correct_answer)

View File

@@ -1,76 +0,0 @@
import numpy as np
import pytest
from skimage._shared._dependency_checks import has_mpl
from skimage.feature.util import (FeatureDetector, DescriptorExtractor,
_prepare_grayscale_input_2D,
_mask_border_keypoints, plot_matches)
def test_feature_detector():
with pytest.raises(NotImplementedError):
FeatureDetector().detect(None)
def test_descriptor_extractor():
with pytest.raises(NotImplementedError):
DescriptorExtractor().extract(None, None)
def test_prepare_grayscale_input_2D():
with pytest.raises(ValueError):
_prepare_grayscale_input_2D(np.zeros((3, 3, 3)))
with pytest.raises(ValueError):
_prepare_grayscale_input_2D(np.zeros((3, 1)))
with pytest.raises(ValueError):
_prepare_grayscale_input_2D(np.zeros((3, 1, 1)))
_prepare_grayscale_input_2D(np.zeros((3, 3)))
_prepare_grayscale_input_2D(np.zeros((3, 3, 1)))
_prepare_grayscale_input_2D(np.zeros((1, 3, 3)))
def test_mask_border_keypoints():
keypoints = np.array([[0, 0], [1, 1], [2, 2], [3, 3], [4, 4]])
np.testing.assert_equal(_mask_border_keypoints((10, 10), keypoints, 0),
[1, 1, 1, 1, 1])
np.testing.assert_equal(_mask_border_keypoints((10, 10), keypoints, 2),
[0, 0, 1, 1, 1])
np.testing.assert_equal(_mask_border_keypoints((4, 4), keypoints, 2),
[0, 0, 1, 0, 0])
np.testing.assert_equal(_mask_border_keypoints((10, 10), keypoints, 5),
[0, 0, 0, 0, 0])
np.testing.assert_equal(_mask_border_keypoints((10, 10), keypoints, 4),
[0, 0, 0, 0, 1])
@pytest.mark.skipif(not has_mpl, reason="Matplotlib not installed")
def test_plot_matches():
from matplotlib import pyplot as plt
fig, ax = plt.subplots(nrows=1, ncols=1)
shapes = (((10, 10), (10, 10)),
((10, 10), (12, 10)),
((10, 10), (10, 12)),
((10, 10), (12, 12)),
((12, 10), (10, 10)),
((10, 12), (10, 10)),
((12, 12), (10, 10)))
keypoints1 = 10 * np.random.rand(10, 2)
keypoints2 = 10 * np.random.rand(10, 2)
idxs1 = np.random.randint(10, size=10)
idxs2 = np.random.randint(10, size=10)
matches = np.column_stack((idxs1, idxs2))
for shape1, shape2 in shapes:
img1 = np.zeros(shape1)
img2 = np.zeros(shape2)
plot_matches(ax, img1, img2, keypoints1, keypoints2, matches)
plot_matches(ax, img1, img2, keypoints1, keypoints2, matches,
only_matches=True)
plot_matches(ax, img1, img2, keypoints1, keypoints2, matches,
keypoints_color='r')
plot_matches(ax, img1, img2, keypoints1, keypoints2, matches,
matches_color='r')
plot_matches(ax, img1, img2, keypoints1, keypoints2, matches,
alignment='vertical')