Fixed database typo and removed unnecessary class identifier.
This commit is contained in:
parent
00ad49a143
commit
45fb349a7d
5098 changed files with 952558 additions and 85 deletions
9
venv/Lib/site-packages/skimage/feature/tests/__init__.py
Normal file
9
venv/Lib/site-packages/skimage/feature/tests/__init__.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
from ..._shared.testing import setup_test, teardown_test
|
||||
|
||||
|
||||
def setup():
|
||||
setup_test()
|
||||
|
||||
|
||||
def teardown():
|
||||
teardown_test()
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
445
venv/Lib/site-packages/skimage/feature/tests/test_blob.py
Normal file
445
venv/Lib/site-packages/skimage/feature/tests/test_blob.py
Normal file
|
@ -0,0 +1,445 @@
|
|||
import numpy as np
|
||||
from skimage.draw import disk
|
||||
from skimage.draw.draw3d import ellipsoid
|
||||
from skimage.feature import blob_dog, blob_log, blob_doh
|
||||
from skimage.feature.blob import _blob_overlap
|
||||
import math
|
||||
from numpy.testing import assert_almost_equal
|
||||
|
||||
|
||||
def test_blob_dog():
|
||||
r2 = math.sqrt(2)
|
||||
img = np.ones((512, 512))
|
||||
|
||||
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
|
||||
|
||||
blobs = blob_dog(img, min_sigma=5, max_sigma=50)
|
||||
radius = lambda x: r2 * x[2]
|
||||
s = sorted(blobs, key=radius)
|
||||
thresh = 5
|
||||
|
||||
b = s[0]
|
||||
assert abs(b[0] - 400) <= thresh
|
||||
assert abs(b[1] - 130) <= thresh
|
||||
assert abs(radius(b) - 5) <= thresh
|
||||
|
||||
b = s[1]
|
||||
assert abs(b[0] - 100) <= thresh
|
||||
assert abs(b[1] - 300) <= thresh
|
||||
assert abs(radius(b) - 25) <= thresh
|
||||
|
||||
b = s[2]
|
||||
assert abs(b[0] - 200) <= thresh
|
||||
assert abs(b[1] - 350) <= thresh
|
||||
assert abs(radius(b) - 45) <= thresh
|
||||
|
||||
# Testing no peaks
|
||||
img_empty = np.zeros((100,100))
|
||||
assert blob_dog(img_empty).size == 0
|
||||
|
||||
# Testing 3D
|
||||
r = 10
|
||||
pad = 10
|
||||
im3 = ellipsoid(r, r, r)
|
||||
im3 = np.pad(im3, pad, mode='constant')
|
||||
|
||||
blobs = blob_dog(im3, min_sigma=3, max_sigma=10,
|
||||
sigma_ratio=1.2, threshold=0.1)
|
||||
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
|
||||
|
||||
# Testing 3D anisotropic
|
||||
r = 10
|
||||
pad = 10
|
||||
im3 = ellipsoid(r / 2, r, r)
|
||||
im3 = np.pad(im3, pad, mode='constant')
|
||||
|
||||
blobs = blob_dog(
|
||||
im3,
|
||||
min_sigma=[1.5, 3, 3],
|
||||
max_sigma=[5, 10, 10],
|
||||
sigma_ratio=1.2,
|
||||
threshold=0.1
|
||||
)
|
||||
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
|
||||
|
||||
# Testing exclude border
|
||||
|
||||
# image where blob is 5 px from borders, radius 5
|
||||
img = np.ones((512, 512))
|
||||
xs, ys = disk((5, 5), 5)
|
||||
img[xs, ys] = 255
|
||||
|
||||
|
||||
def test_blob_dog_excl_border():
|
||||
img = np.ones((512, 512))
|
||||
xs, ys = disk((5, 5), 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
|
||||
b = blobs[0]
|
||||
assert b[0] == b[1] == 5, "blob should be 5 px from x and y borders"
|
||||
|
||||
blobs = blob_dog(
|
||||
img,
|
||||
min_sigma=1.5,
|
||||
max_sigma=5,
|
||||
sigma_ratio=1.2,
|
||||
exclude_border=6,
|
||||
)
|
||||
msg = "zero blobs should be detected, as only blob is 5 px from border"
|
||||
assert blobs.shape[0] == 0, msg
|
||||
|
||||
|
||||
def test_blob_log():
|
||||
r2 = math.sqrt(2)
|
||||
img = np.ones((256, 256))
|
||||
|
||||
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
|
||||
|
||||
blobs = blob_log(img, min_sigma=5, max_sigma=20, threshold=1)
|
||||
|
||||
radius = lambda x: 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=1,
|
||||
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_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
|
||||
|
||||
|
||||
def test_blob_log_exclude_border():
|
||||
# image where blob is 5 px from borders, radius 5
|
||||
img = np.ones((512, 512))
|
||||
xs, ys = disk((5, 5), 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] == b[1] == 5, "blob should be 5 px from x and y borders"
|
||||
|
||||
blobs = blob_log(
|
||||
img,
|
||||
min_sigma=1.5,
|
||||
max_sigma=5,
|
||||
exclude_border=6,
|
||||
)
|
||||
msg = "zero blobs should be detected, as only blob is 5 px from border"
|
||||
assert blobs.shape[0] == 0, msg
|
||||
|
||||
|
||||
def test_blob_doh():
|
||||
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,
|
||||
threshold=.05)
|
||||
|
||||
radius = lambda x: 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)
|
||||
|
||||
radius = lambda x: 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
|
80
venv/Lib/site-packages/skimage/feature/tests/test_brief.py
Normal file
80
venv/Lib/site-packages/skimage/feature/tests/test_brief.py
Normal file
|
@ -0,0 +1,80 @@
|
|||
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, 0, 1, 0, 0, 1, 0, 1],
|
||||
[1, 1, 1, 0, 1, 0, 1, 1],
|
||||
[1, 0, 1, 0, 0, 1, 0, 1],
|
||||
[0, 1, 0, 0, 1, 0, 1, 0],
|
||||
[1, 1, 1, 0, 0, 0, 1, 1],
|
||||
[1, 1, 1, 0, 1, 1, 1, 1],
|
||||
[1, 0, 1, 0, 0, 1, 0, 1],
|
||||
[0, 0, 0, 0, 0, 1, 0, 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([[1, 1, 0, 0, 0, 0, 0, 0],
|
||||
[1, 1, 1, 0, 0, 1, 0, 0],
|
||||
[1, 1, 0, 0, 1, 0, 0, 0],
|
||||
[0, 0, 0, 1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 0, 0, 1, 0, 0],
|
||||
[1, 1, 1, 1, 0, 1, 0, 0],
|
||||
[1, 1, 0, 0, 0, 1, 0, 0],
|
||||
[0, 1, 1, 1, 0, 1, 1, 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))
|
121
venv/Lib/site-packages/skimage/feature/tests/test_canny.py
Normal file
121
venv/Lib/site-packages/skimage/feature/tests/test_canny.py
Normal file
|
@ -0,0 +1,121 @@
|
|||
import unittest
|
||||
import numpy as np
|
||||
from skimage._shared.testing import assert_equal
|
||||
from scipy.ndimage import binary_dilation, binary_erosion
|
||||
import skimage.feature as F
|
||||
from skimage import data, 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 = F.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 = (F.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 = F.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 = F.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, F.canny, np.zeros((20, 20, 20)), 4, 0, 0)
|
||||
|
||||
def test_mask_none(self):
|
||||
result1 = F.canny(np.zeros((20, 20)), 4, 0, 0, np.ones((20, 20), bool))
|
||||
result2 = F.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()[::50, ::50])
|
||||
|
||||
# Correct output produced manually with quantiles
|
||||
# of 0.8 and 0.6 for high and low respectively
|
||||
correct_output = 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, 0, 1, 1, 1, 0, 0, 0, 0],
|
||||
[0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0],
|
||||
[0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0],
|
||||
[0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=bool)
|
||||
|
||||
result = F.canny(image, low_threshold=0.6, high_threshold=0.8, use_quantiles=True)
|
||||
|
||||
assert_equal(result, correct_output)
|
||||
|
||||
def test_invalid_use_quantiles(self):
|
||||
image = img_as_float(data.camera()[::50, ::50])
|
||||
|
||||
self.assertRaises(ValueError, F.canny, image, use_quantiles=True,
|
||||
low_threshold=0.5, high_threshold=3.6)
|
||||
|
||||
self.assertRaises(ValueError, F.canny, image, use_quantiles=True,
|
||||
low_threshold=-5, high_threshold=0.5)
|
||||
|
||||
self.assertRaises(ValueError, F.canny, image, use_quantiles=True,
|
||||
low_threshold=99, high_threshold=0.9)
|
||||
|
||||
self.assertRaises(ValueError, F.canny, image, use_quantiles=True,
|
||||
low_threshold=0.5, high_threshold=-100)
|
||||
|
||||
# Example from issue #4282
|
||||
image = data.camera()
|
||||
self.assertRaises(ValueError, F.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 = F.canny(image_uint8)
|
||||
result_float = F.canny(image_float)
|
||||
|
||||
assert_equal(result_uint8, result_float)
|
23
venv/Lib/site-packages/skimage/feature/tests/test_cascade.py
Normal file
23
venv/Lib/site-packages/skimage/feature/tests/test_cascade.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
import numpy as np
|
||||
|
||||
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.'
|
105
venv/Lib/site-packages/skimage/feature/tests/test_censure.py
Normal file
105
venv/Lib/site-packages/skimage/feature/tests/test_censure.py
Normal file
|
@ -0,0 +1,105 @@
|
|||
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,
|
||||
multichannel=False,
|
||||
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,
|
||||
multichannel=False,
|
||||
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)
|
493
venv/Lib/site-packages/skimage/feature/tests/test_corner.py
Normal file
493
venv/Lib/site-packages/skimage/feature/tests/test_corner.py
Normal file
|
@ -0,0 +1,493 @@
|
|||
import numpy as np
|
||||
from skimage._shared.testing import assert_array_equal, assert_almost_equal
|
||||
from skimage import data
|
||||
from skimage import img_as_float
|
||||
from skimage import draw
|
||||
from skimage.color import rgb2gray
|
||||
from skimage.morphology import octagon
|
||||
from skimage._shared.testing import test_parallel
|
||||
from skimage._shared._warnings import expected_warnings
|
||||
from skimage._shared import testing
|
||||
import pytest
|
||||
|
||||
from skimage.feature import (corner_moravec, corner_harris, corner_shi_tomasi,
|
||||
corner_subpix, peak_local_max, corner_peaks,
|
||||
corner_kitchen_rosenfeld, corner_foerstner,
|
||||
corner_fast, corner_orientations,
|
||||
structure_tensor, structure_tensor_eigvals,
|
||||
hessian_matrix, hessian_matrix_eigvals,
|
||||
hessian_matrix_det, shape_index)
|
||||
|
||||
|
||||
@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
|
||||
|
||||
|
||||
def test_structure_tensor():
|
||||
square = np.zeros((5, 5))
|
||||
square[2, 2] = 1
|
||||
Axx, Axy, Ayy = structure_tensor(square, sigma=0.1)
|
||||
assert_array_equal(Axx, 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(Axy, 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(Ayy, 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]]))
|
||||
|
||||
|
||||
def test_hessian_matrix():
|
||||
square = np.zeros((5, 5))
|
||||
square[2, 2] = 4
|
||||
Hrr, Hrc, Hcc = hessian_matrix(square, sigma=0.1, order='rc')
|
||||
assert_almost_equal(Hrr, 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]]))
|
||||
|
||||
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, 2, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, -2, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 2, 0, 0]]))
|
||||
|
||||
|
||||
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')
|
||||
assert len(Hs) == 6, ("incorrect number of Hessian images (%i) for 3D" %
|
||||
len(Hs))
|
||||
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]]))
|
||||
|
||||
|
||||
def test_structure_tensor_eigvals():
|
||||
square = np.zeros((5, 5))
|
||||
square[2, 2] = 1
|
||||
Axx, Axy, Ayy = structure_tensor(square, sigma=0.1)
|
||||
l1, l2 = structure_tensor_eigvals(Axx, Axy, Ayy)
|
||||
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_hessian_matrix_eigvals():
|
||||
square = np.zeros((5, 5))
|
||||
square[2, 2] = 4
|
||||
H = hessian_matrix(square, sigma=0.1, order='rc')
|
||||
l1, l2 = hessian_matrix_eigvals(H)
|
||||
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]]))
|
||||
|
||||
|
||||
def test_hessian_matrix_eigvals_3d(im3d):
|
||||
H = hessian_matrix(im3d)
|
||||
E = hessian_matrix_eigvals(H)
|
||||
# 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)
|
||||
|
||||
|
||||
def test_hessian_matrix_det_3d(im3d):
|
||||
D = hessian_matrix_det(im3d)
|
||||
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 = peak_local_max(corner_moravec(im),
|
||||
min_distance=10, threshold_rel=0)
|
||||
# interest points along edge
|
||||
assert len(results) == 57
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
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 = peak_local_max(corner_moravec(im),
|
||||
min_distance=10, threshold_rel=0)
|
||||
results_rotated = peak_local_max(corner_moravec(im_rotated),
|
||||
min_distance=10, threshold_rel=0)
|
||||
assert (np.sort(results[:, 0]) == np.sort(results_rotated[:, 1])).all()
|
||||
assert (np.sort(results[:, 1]) == np.sort(results_rotated[:, 0])).all()
|
||||
|
||||
# Harris
|
||||
results = peak_local_max(corner_harris(im),
|
||||
min_distance=10, threshold_rel=0)
|
||||
results_rotated = peak_local_max(corner_harris(im_rotated),
|
||||
min_distance=10, threshold_rel=0)
|
||||
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 = peak_local_max(corner_shi_tomasi(im),
|
||||
min_distance=10, threshold_rel=0)
|
||||
results_rotated = peak_local_max(corner_shi_tomasi(im_rotated),
|
||||
min_distance=10, threshold_rel=0)
|
||||
assert (np.sort(results[:, 0]) == np.sort(results_rotated[:, 1])).all()
|
||||
assert (np.sort(results[:, 1]) == np.sort(results_rotated[:, 0])).all()
|
||||
|
||||
|
||||
def test_subpix_edge():
|
||||
img = np.zeros((50, 50))
|
||||
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_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, np.array([[25, 25]]))
|
||||
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)
|
||||
|
||||
with pytest.warns(FutureWarning,
|
||||
match="Until version 0.16, threshold_rel.*"):
|
||||
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 testing.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 testing.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 testing.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)
|
||||
|
||||
|
||||
def test_corner_orientations_square():
|
||||
square = np.zeros((12, 12))
|
||||
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))
|
||||
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)
|
102
venv/Lib/site-packages/skimage/feature/tests/test_daisy.py
Normal file
102
venv/Lib/site-packages/skimage/feature/tests/test_daisy.py
Normal file
|
@ -0,0 +1,102 @@
|
|||
import numpy as np
|
||||
from skimage._shared.testing import assert_almost_equal
|
||||
from numpy import sqrt, ceil
|
||||
|
||||
from skimage import data
|
||||
from skimage import img_as_float
|
||||
from skimage.feature import daisy
|
||||
from skimage._shared import testing
|
||||
|
||||
|
||||
def test_daisy_color_image_unsupported_error():
|
||||
img = np.zeros((20, 20, 3))
|
||||
with testing.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)))
|
||||
|
||||
|
||||
def test_daisy_sigmas_and_radii():
|
||||
img = img_as_float(data.astronaut()[:64, :64].mean(axis=2))
|
||||
sigmas = [1, 2, 3]
|
||||
radii = [1, 2]
|
||||
daisy(img, sigmas=sigmas, ring_radii=radii)
|
||||
|
||||
|
||||
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 testing.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 testing.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))
|
153
venv/Lib/site-packages/skimage/feature/tests/test_haar.py
Normal file
153
venv/Lib/site-packages/skimage/feature/tests/test_haar.py
Normal file
|
@ -0,0 +1,153 @@
|
|||
from random import shuffle
|
||||
from itertools import chain
|
||||
|
||||
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,), [-4., -3., -2., -1.]),
|
||||
('type-3-y', (42,), [-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)]],
|
||||
[[(1, 0), (1, 0)], [(1, 1), (1, 1)]]]),
|
||||
('type-2-y', 2, 2,
|
||||
[[[(0, 0), (0, 0)], [(1, 0), (1, 0)]],
|
||||
[[(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)]],
|
||||
[[(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, 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, 8)])
|
||||
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
|
256
venv/Lib/site-packages/skimage/feature/tests/test_hog.py
Normal file
256
venv/Lib/site-packages/skimage/feature/tests/test_hog.py
Normal file
|
@ -0,0 +1,256 @@
|
|||
import os
|
||||
import numpy as np
|
||||
from scipy import ndimage as ndi
|
||||
from skimage import color
|
||||
from skimage import data
|
||||
from skimage import feature
|
||||
from skimage import img_as_float
|
||||
from skimage import draw
|
||||
from skimage._shared.testing import assert_almost_equal, fetch
|
||||
from skimage._shared import testing
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
def test_hog_output_correctness_l1_norm():
|
||||
img = color.rgb2gray(data.astronaut())
|
||||
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)
|
||||
assert_almost_equal(output, correct_output)
|
||||
|
||||
|
||||
def test_hog_output_correctness_l2hys_norm():
|
||||
img = color.rgb2gray(data.astronaut())
|
||||
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)
|
||||
assert_almost_equal(output, correct_output)
|
||||
|
||||
|
||||
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_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 = ndi.gaussian_filter(image, 2)
|
||||
|
||||
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, '
|
||||
'orientations=%d' % (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 testing.raises(ValueError):
|
||||
feature.hog(img, block_norm='Linf')
|
||||
|
||||
|
||||
@testing.parametrize("shape,multichannel", [
|
||||
((3, 3, 3), False),
|
||||
((3, 3), True),
|
||||
((3, 3, 3, 3), True),
|
||||
])
|
||||
def test_hog_incorrect_dimensions(shape, multichannel):
|
||||
img = np.zeros(shape)
|
||||
with testing.raises(ValueError):
|
||||
feature.hog(img, multichannel=multichannel, block_norm='L1')
|
||||
|
||||
|
||||
def test_hog_output_equivariance_multichannel():
|
||||
img = data.astronaut()
|
||||
img[:, :, (1, 2)] = 0
|
||||
hog_ref = feature.hog(img, multichannel=True, block_norm='L1')
|
||||
|
||||
for n in (1, 2):
|
||||
hog_fact = feature.hog(np.roll(img, n, axis=2), multichannel=True,
|
||||
block_norm='L1')
|
||||
assert_almost_equal(hog_ref, hog_fact)
|
179
venv/Lib/site-packages/skimage/feature/tests/test_match.py
Normal file
179
venv/Lib/site-packages/skimage/feature/tests/test_match.py
Normal file
|
@ -0,0 +1,179 @@
|
|||
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, 34, 18, 24, 27,
|
||||
30, 25, 26, 32, 28, 35, 37, 42, 29, 38,
|
||||
33, 40, 36, 3, 10, 32, 43, 15, 29, 41,
|
||||
1, 18, 32, 24, 11])
|
||||
|
||||
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, 25, 26, 27, 28, 29, 30, 31, 32, 33,
|
||||
34, 38, 41])
|
||||
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, 32, 28, 35, 37, 42, 29, 38, 33,
|
||||
40, 36, 43, 41])
|
||||
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)
|
131
venv/Lib/site-packages/skimage/feature/tests/test_orb.py
Normal file
131
venv/Lib/site-packages/skimage/feature/tests/test_orb.py
Normal file
|
@ -0,0 +1,131 @@
|
|||
import pytest
|
||||
import numpy as np
|
||||
|
||||
from skimage._shared.testing import assert_equal, assert_almost_equal
|
||||
from skimage.feature import ORB
|
||||
from skimage._shared import testing
|
||||
from skimage import data
|
||||
from skimage._shared.testing import test_parallel, xfail, arch32
|
||||
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])
|
||||
|
||||
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 testing.raises(RuntimeError):
|
||||
detector_extractor.detect_and_extract(img)
|
537
venv/Lib/site-packages/skimage/feature/tests/test_peak.py
Normal file
537
venv/Lib/site-packages/skimage/feature/tests/test_peak.py
Normal file
|
@ -0,0 +1,537 @@
|
|||
import itertools
|
||||
import numpy as np
|
||||
import pytest
|
||||
import unittest
|
||||
from skimage._shared.testing import assert_array_almost_equal
|
||||
from skimage._shared.testing import assert_equal
|
||||
from scipy import ndimage as ndi
|
||||
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, indices=True)
|
||||
assert type(peak_indices) is np.ndarray
|
||||
assert peak_indices.size == 0
|
||||
peaks = peak.peak_local_max(trivial, min_distance=1, indices=False)
|
||||
assert (peaks.astype(np.bool) == trivial).all()
|
||||
|
||||
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,
|
||||
indices=True,
|
||||
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,
|
||||
indices=True,
|
||||
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,
|
||||
indices=True,
|
||||
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)
|
||||
result = peak.peak_local_max(image, labels=labels, min_distance=1,
|
||||
threshold_rel=0, footprint=footprint,
|
||||
indices=False, exclude_border=False)
|
||||
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.transpose(np.nonzero(expected == image))
|
||||
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,
|
||||
indices=True, exclude_border=False)
|
||||
result = result[np.argsort(image[tuple(result.T)])[::-1]]
|
||||
assert (result == expected).all()
|
||||
|
||||
def test_ndarray_indices_false(self):
|
||||
nd_image = np.zeros((5, 5, 5))
|
||||
nd_image[2, 2, 2] = 1
|
||||
peaks = peak.peak_local_max(nd_image, min_distance=1, indices=False)
|
||||
assert (peaks == nd_image.astype(np.bool)).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.zeros_like(nd_image, dtype=np.bool)
|
||||
expected[2, 2, 2] = True
|
||||
expectedNoBorder = nd_image > 0
|
||||
result = peak.peak_local_max(nd_image, min_distance=2,
|
||||
exclude_border=2, indices=False)
|
||||
assert_equal(result, expected)
|
||||
# Check that bools work as expected
|
||||
assert_equal(
|
||||
peak.peak_local_max(nd_image, min_distance=2,
|
||||
exclude_border=2, indices=False),
|
||||
peak.peak_local_max(nd_image, min_distance=2,
|
||||
exclude_border=True, indices=False)
|
||||
)
|
||||
assert_equal(
|
||||
peak.peak_local_max(nd_image, min_distance=2,
|
||||
exclude_border=0, indices=False),
|
||||
peak.peak_local_max(nd_image, min_distance=2,
|
||||
exclude_border=False, indices=False)
|
||||
)
|
||||
# Check both versions with no border
|
||||
assert_equal(
|
||||
peak.peak_local_max(nd_image, min_distance=2,
|
||||
exclude_border=0, indices=False),
|
||||
expectedNoBorder,
|
||||
)
|
||||
assert_equal(
|
||||
peak.peak_local_max(nd_image,
|
||||
exclude_border=False, indices=False),
|
||||
expectedNoBorder,
|
||||
)
|
||||
|
||||
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,
|
||||
indices=False, exclude_border=False)
|
||||
assert np.all(~ result)
|
||||
|
||||
def test_empty_non2d_indices(self):
|
||||
image = np.zeros((10, 10, 10))
|
||||
result = peak.peak_local_max(image,
|
||||
footprint=np.ones((3, 3), bool),
|
||||
min_distance=1, threshold_rel=0,
|
||||
indices=True, 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
|
||||
result = peak.peak_local_max(image, labels=labels,
|
||||
footprint=np.ones((3, 3), bool),
|
||||
min_distance=1, threshold_rel=0,
|
||||
indices=False, exclude_border=False)
|
||||
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
|
||||
result = peak.peak_local_max(image, labels=labels,
|
||||
footprint=np.ones((3, 3), bool),
|
||||
min_distance=1, threshold_rel=0,
|
||||
indices=False, exclude_border=False)
|
||||
assert np.all(result == (labels == 1))
|
||||
|
||||
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 = (image == 1)
|
||||
result = peak.peak_local_max(image, labels=labels,
|
||||
footprint=np.ones((3, 3), bool),
|
||||
min_distance=1, threshold_rel=0,
|
||||
indices=False, exclude_border=False)
|
||||
assert np.all(result == expected)
|
||||
result = peak.peak_local_max(image, labels=labels,
|
||||
min_distance=1, threshold_rel=0,
|
||||
indices=False, exclude_border=False)
|
||||
assert np.all(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 = (labels == 1)
|
||||
result = peak.peak_local_max(image, labels=labels,
|
||||
footprint=np.ones((3, 3), bool),
|
||||
min_distance=1, threshold_rel=0,
|
||||
indices=False, exclude_border=False)
|
||||
assert np.all(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 = (labels > 0)
|
||||
result = peak.peak_local_max(image, labels=labels,
|
||||
footprint=np.ones((3, 3), bool),
|
||||
min_distance=1, threshold_rel=0,
|
||||
indices=False, exclude_border=False)
|
||||
assert np.all(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 = (labels > 0)
|
||||
result = peak.peak_local_max(image, labels=labels,
|
||||
footprint=np.ones((3, 3), bool),
|
||||
min_distance=1, threshold_rel=0,
|
||||
indices=False, exclude_border=False)
|
||||
assert np.all(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)
|
||||
result = peak.peak_local_max(image, labels=labels, footprint=footprint,
|
||||
min_distance=1, threshold_rel=0,
|
||||
indices=False, exclude_border=False)
|
||||
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]])
|
||||
result = peak.peak_local_max(image, labels=np.ones((10, 20)),
|
||||
footprint=footprint,
|
||||
min_distance=1, threshold_rel=0,
|
||||
threshold_abs=-1, indices=False,
|
||||
exclude_border=False)
|
||||
assert np.all(result)
|
||||
result = peak.peak_local_max(image, footprint=footprint, threshold_abs=-1,
|
||||
indices=False, exclude_border=False)
|
||||
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_equal(peak.peak_local_max(image, min_distance=10, threshold_rel=0),
|
||||
[[15, 15, 15]])
|
||||
assert_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_equal(peak.peak_local_max(image, min_distance=10, threshold_rel=0),
|
||||
[[15, 15, 15, 15]])
|
||||
assert_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_equal(peak.peak_local_max(image), [[2, 2]])
|
||||
|
||||
image[2, 2] = 0
|
||||
assert len(peak.peak_local_max(image, min_distance=0)) == image.size - 1
|
||||
|
||||
|
||||
@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)
|
||||
|
||||
|
||||
class TestProminentPeaks(unittest.TestCase):
|
||||
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]):
|
||||
self.assertTrue(i in (i0, i1, i2))
|
||||
self.assertTrue(x in (x0, x1, x2))
|
||||
self.assertTrue(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]):
|
||||
self.assertTrue(i in (i0, i1, i2))
|
||||
self.assertTrue(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]):
|
||||
self.assertTrue(i in (i0, i2))
|
||||
self.assertTrue(x in (x0, x2))
|
||||
self.assertTrue(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] = 1
|
||||
labelsin = labels.copy()
|
||||
result = peak.peak_local_max(image, labels=labels,
|
||||
footprint=np.ones((3, 3), bool),
|
||||
min_distance=1, threshold_rel=0,
|
||||
indices=False, 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, indices=True,
|
||||
exclude_border=False, labels=labels)
|
||||
assert len(local_max) == 625
|
186
venv/Lib/site-packages/skimage/feature/tests/test_template.py
Normal file
186
venv/Lib/site-packages/skimage/feature/tests/test_template.py
Normal file
|
@ -0,0 +1,186 @@
|
|||
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
|
||||
|
||||
|
||||
def test_template():
|
||||
size = 100
|
||||
# Float prefactors ensure that image range is between 0 and 1
|
||||
image = np.full((400, 400), 0.5)
|
||||
target = 0.1 * (np.tri(size) + np.tri(size)[::-1])
|
||||
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))
|
||||
|
||||
result = match_template(image, target)
|
||||
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(img_as_float(data.page()), template)
|
||||
print(result.max())
|
||||
assert result.max() < 1 + 1e-7
|
||||
assert result.min() > -1 - 1e-7
|
294
venv/Lib/site-packages/skimage/feature/tests/test_texture.py
Normal file
294
venv/Lib/site-packages/skimage/feature/tests/test_texture.py
Normal file
|
@ -0,0 +1,294 @@
|
|||
import numpy as np
|
||||
from skimage.feature import (greycomatrix,
|
||||
greycoprops,
|
||||
local_binary_pattern,
|
||||
multiblock_lbp)
|
||||
from skimage._shared.testing import test_parallel
|
||||
from skimage.transform import integral_image
|
||||
from skimage._shared import testing
|
||||
|
||||
|
||||
class TestGLCM():
|
||||
|
||||
def setup(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 = greycomatrix(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 = greycomatrix(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 [np.float, np.double, np.float16, np.float32, np.float64]:
|
||||
with testing.raises(ValueError):
|
||||
greycomatrix(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 testing.raises(ValueError):
|
||||
greycomatrix(self.image.astype(dtype), [1], [np.pi])
|
||||
|
||||
def test_error_raise_negative(self):
|
||||
with testing.raises(ValueError):
|
||||
greycomatrix(self.image.astype(np.int16) - 1, [1], [np.pi], 4)
|
||||
|
||||
def test_error_raise_levels_smaller_max(self):
|
||||
with testing.raises(ValueError):
|
||||
greycomatrix(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 = greycomatrix(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 = greycomatrix(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 = greycomatrix(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 = greycomatrix(self.image, [10], [0], 4)
|
||||
np.testing.assert_array_equal(result[:, :, 0, 0],
|
||||
np.zeros((4, 4), dtype=np.uint32))
|
||||
result = greycomatrix(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 = greycomatrix(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 = greycomatrix(self.image, [1, 2], [0], 4,
|
||||
normed=True, symmetric=True)
|
||||
result = np.round(result, 3)
|
||||
contrast = greycoprops(result, 'contrast')
|
||||
np.testing.assert_almost_equal(contrast[0, 0], 0.585, decimal=3)
|
||||
|
||||
def test_dissimilarity(self):
|
||||
result = greycomatrix(self.image, [1], [0, np.pi / 2], 4,
|
||||
normed=True, symmetric=True)
|
||||
result = np.round(result, 3)
|
||||
dissimilarity = greycoprops(result, 'dissimilarity')
|
||||
np.testing.assert_almost_equal(dissimilarity[0, 0], 0.418, decimal=3)
|
||||
|
||||
def test_dissimilarity_2(self):
|
||||
result = greycomatrix(self.image, [1, 3], [np.pi / 2], 4,
|
||||
normed=True, symmetric=True)
|
||||
result = np.round(result, 3)
|
||||
dissimilarity = greycoprops(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 = greycomatrix(img, [1, 2, 4, 5], [0, 0.25, 1, 1.5], levels=8)
|
||||
np.testing.assert_(np.max(greycoprops(p, 'correlation')) < 1.0)
|
||||
|
||||
def test_invalid_property(self):
|
||||
result = greycomatrix(self.image, [1], [0], 4)
|
||||
with testing.raises(ValueError):
|
||||
greycoprops(result, 'ABC')
|
||||
|
||||
def test_homogeneity(self):
|
||||
result = greycomatrix(self.image, [1], [0, 6], 4, normed=True,
|
||||
symmetric=True)
|
||||
homogeneity = greycoprops(result, 'homogeneity')[0, 0]
|
||||
np.testing.assert_almost_equal(homogeneity, 0.80833333)
|
||||
|
||||
def test_energy(self):
|
||||
result = greycomatrix(self.image, [1], [0, 4], 4, normed=True,
|
||||
symmetric=True)
|
||||
energy = greycoprops(result, 'energy')[0, 0]
|
||||
np.testing.assert_almost_equal(energy, 0.38188131)
|
||||
|
||||
def test_correlation(self):
|
||||
result = greycomatrix(self.image, [1, 2], [0], 4, normed=True,
|
||||
symmetric=True)
|
||||
energy = greycoprops(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 = greycomatrix(im, [1, 2, 8], [0, np.pi / 2], 4, normed=True,
|
||||
symmetric=True)
|
||||
for prop in ['contrast', 'dissimilarity', 'homogeneity',
|
||||
'energy', 'correlation', 'ASM']:
|
||||
greycoprops(result, prop)
|
||||
|
||||
|
||||
class TestLBP():
|
||||
|
||||
def setup(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='double')
|
||||
|
||||
@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)
|
||||
|
||||
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
|
||||
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)
|
81
venv/Lib/site-packages/skimage/feature/tests/test_util.py
Normal file
81
venv/Lib/site-packages/skimage/feature/tests/test_util.py
Normal file
|
@ -0,0 +1,81 @@
|
|||
import numpy as np
|
||||
try:
|
||||
import matplotlib.pyplot as plt
|
||||
except ImportError:
|
||||
plt = None
|
||||
|
||||
from skimage._shared.testing import assert_equal
|
||||
|
||||
from skimage.feature.util import (FeatureDetector, DescriptorExtractor,
|
||||
_prepare_grayscale_input_2D,
|
||||
_mask_border_keypoints, plot_matches)
|
||||
|
||||
from skimage._shared import testing
|
||||
|
||||
|
||||
def test_feature_detector():
|
||||
with testing.raises(NotImplementedError):
|
||||
FeatureDetector().detect(None)
|
||||
|
||||
|
||||
def test_descriptor_extractor():
|
||||
with testing.raises(NotImplementedError):
|
||||
DescriptorExtractor().extract(None, None)
|
||||
|
||||
|
||||
def test_prepare_grayscale_input_2D():
|
||||
with testing.raises(ValueError):
|
||||
_prepare_grayscale_input_2D(np.zeros((3, 3, 3)))
|
||||
with testing.raises(ValueError):
|
||||
_prepare_grayscale_input_2D(np.zeros((3, 1)))
|
||||
with testing.raises(ValueError):
|
||||
_prepare_grayscale_input_2D(np.zeros((3, 1, 1)))
|
||||
img = _prepare_grayscale_input_2D(np.zeros((3, 3)))
|
||||
img = _prepare_grayscale_input_2D(np.zeros((3, 3, 1)))
|
||||
img = _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]])
|
||||
assert_equal(_mask_border_keypoints((10, 10), keypoints, 0),
|
||||
[1, 1, 1, 1, 1])
|
||||
assert_equal(_mask_border_keypoints((10, 10), keypoints, 2),
|
||||
[0, 0, 1, 1, 1])
|
||||
assert_equal(_mask_border_keypoints((4, 4), keypoints, 2),
|
||||
[0, 0, 1, 0, 0])
|
||||
assert_equal(_mask_border_keypoints((10, 10), keypoints, 5),
|
||||
[0, 0, 0, 0, 0])
|
||||
assert_equal(_mask_border_keypoints((10, 10), keypoints, 4),
|
||||
[0, 0, 0, 0, 1])
|
||||
|
||||
|
||||
@testing.skipif(plt is None, reason="Matplotlib not installed")
|
||||
def test_plot_matches():
|
||||
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')
|
Loading…
Add table
Add a link
Reference in a new issue