import numpy as np
import pytest
import scirs2
class TestImageFilters:
def test_gaussian_filter(self):
image = np.random.randn(32, 32)
filtered = scirs2.gaussian_filter_py(image, sigma=1.0)
assert filtered.shape == image.shape
assert np.var(filtered) < np.var(image)
def test_uniform_filter(self):
image = np.random.randn(32, 32)
filtered = scirs2.uniform_filter_py(image, size=3)
assert filtered.shape == image.shape
def test_median_filter(self):
image = np.random.randn(32, 32)
image[10, 10] = 1000
image[20, 20] = -1000
filtered = scirs2.median_filter_py(image, size=3)
assert np.abs(filtered[10, 10]) < 100
assert np.abs(filtered[20, 20]) < 100
def test_sobel_filter(self):
image = np.random.randn(64, 64)
edges = scirs2.sobel_filter_py(image)
assert edges.shape == image.shape
def test_prewitt_filter(self):
image = np.random.randn(64, 64)
edges = scirs2.prewitt_filter_py(image)
assert edges.shape == image.shape
def test_laplacian_filter(self):
image = np.random.randn(32, 32)
filtered = scirs2.laplacian_filter_py(image)
assert filtered.shape == image.shape
class TestMorphology:
def test_binary_erosion(self):
image = np.ones((32, 32), dtype=np.uint8)
image[10:20, 10:20] = 0
eroded = scirs2.binary_erosion_py(image)
assert eroded.shape == image.shape
def test_binary_dilation(self):
image = np.zeros((32, 32), dtype=np.uint8)
image[15:17, 15:17] = 1
dilated = scirs2.binary_dilation_py(image)
assert np.sum(dilated) > np.sum(image)
def test_binary_opening(self):
image = np.ones((32, 32), dtype=np.uint8)
image[15, 15] = 0
opened = scirs2.binary_opening_py(image)
assert opened.shape == image.shape
def test_binary_closing(self):
image = np.zeros((32, 32), dtype=np.uint8)
image[10:20, 10:20] = 1
image[15, 15] = 0
closed = scirs2.binary_closing_py(image)
assert np.sum(closed) >= np.sum(image)
def test_morphological_gradient(self):
image = np.zeros((32, 32), dtype=np.uint8)
image[10:20, 10:20] = 1
gradient = scirs2.morphological_gradient_py(image)
assert gradient.shape == image.shape
class TestSegmentation:
def test_threshold_otsu(self):
image = np.random.randn(32, 32)
threshold = scirs2.threshold_otsu_py(image)
binary = image > threshold
assert binary.dtype == bool
def test_watershed_segmentation(self):
image = np.zeros((32, 32))
image[10, 10] = 1.0
image[22, 22] = 1.0
labels = scirs2.watershed_py(image)
assert labels.shape == image.shape
assert len(np.unique(labels)) > 1
def test_label_connected_components(self):
image = np.zeros((32, 32), dtype=np.uint8)
image[5:10, 5:10] = 1
image[20:25, 20:25] = 1
labels = scirs2.label_connected_components_py(image)
assert len(np.unique(labels)) >= 2
class TestInterpolation:
def test_zoom(self):
image = np.random.randn(16, 16)
zoomed = scirs2.zoom_py(image, zoom=2.0)
assert zoomed.shape == (32, 32)
def test_rotate(self):
image = np.random.randn(32, 32)
rotated = scirs2.rotate_py(image, angle=45.0)
assert rotated.shape[0] > 0 and rotated.shape[1] > 0
def test_shift(self):
image = np.random.randn(32, 32)
shifted = scirs2.shift_py(image, shift=(5, 5))
assert shifted.shape == image.shape
def test_affine_transform(self):
image = np.random.randn(32, 32)
matrix = np.array([[1.2, 0.0], [0.0, 1.2]])
transformed = scirs2.affine_transform_py(image, matrix)
assert transformed.shape[0] > 0
class TestMeasurements:
def test_center_of_mass(self):
image = np.zeros((32, 32))
image[15:17, 15:17] = 1.0
com = scirs2.center_of_mass_py(image)
assert 14 <= com[0] <= 18
assert 14 <= com[1] <= 18
def test_label_stats(self):
image = np.random.randn(32, 32)
labels = np.zeros((32, 32), dtype=np.int32)
labels[5:15, 5:15] = 1
labels[20:30, 20:30] = 2
stats = scirs2.label_stats_py(image, labels)
assert "mean" in stats or "area" in stats
def test_histogram(self):
image = np.random.randn(100, 100)
hist, bins = scirs2.histogram_py(image, bins=20)
assert len(hist) == 20
assert len(bins) == 21
class TestDistanceTransform:
def test_distance_transform_edt(self):
image = np.zeros((32, 32), dtype=np.uint8)
image[16, 16] = 1
distance = scirs2.distance_transform_edt_py(image)
assert distance[16, 16] == 0
assert distance[0, 0] > distance[16, 16]
def test_distance_transform_cdt(self):
image = np.zeros((32, 32), dtype=np.uint8)
image[16, 16] = 1
distance = scirs2.distance_transform_cdt_py(image)
assert distance.shape == image.shape
class TestFourierFilters:
def test_fourier_gaussian(self):
image = np.random.randn(64, 64)
filtered = scirs2.fourier_gaussian_py(image, sigma=2.0)
assert filtered.shape == image.shape
def test_fourier_ellipsoid(self):
image = np.random.randn(64, 64)
filtered = scirs2.fourier_ellipsoid_py(image, size=10)
assert filtered.shape == image.shape
def test_fourier_shift(self):
image = np.random.randn(32, 32)
shifted = scirs2.fourier_shift_py(image, shift=(5, 5))
assert shifted.shape == image.shape
class TestRankFilters:
def test_minimum_filter(self):
image = np.random.rand(32, 32)
filtered = scirs2.minimum_filter_py(image, size=3)
assert filtered.shape == image.shape
assert np.mean(filtered) <= np.mean(image)
def test_maximum_filter(self):
image = np.random.rand(32, 32)
filtered = scirs2.maximum_filter_py(image, size=3)
assert filtered.shape == image.shape
assert np.mean(filtered) >= np.mean(image)
def test_percentile_filter(self):
image = np.random.rand(32, 32)
filtered = scirs2.percentile_filter_py(image, percentile=50, size=3)
assert filtered.shape == image.shape
class TestGeometricTransforms:
def test_resize(self):
image = np.random.randn(32, 32)
resized = scirs2.resize_ndimage_py(image, output_shape=(64, 64))
assert resized.shape == (64, 64)
def test_rescale(self):
image = np.random.randn(32, 32)
rescaled = scirs2.rescale_py(image, scale=2.0)
assert rescaled.shape == (64, 64)
class TestEdgeCases:
def test_empty_image(self):
image = np.array([])
try:
filtered = scirs2.gaussian_filter_py(image, sigma=1.0)
except Exception:
pass
def test_single_pixel(self):
image = np.array([[1.0]])
filtered = scirs2.gaussian_filter_py(image, sigma=1.0)
assert filtered.shape == (1, 1)
def test_3d_image(self):
image = np.random.randn(16, 16, 16)
try:
filtered = scirs2.gaussian_filter_py(image, sigma=1.0)
assert filtered.shape == image.shape
except Exception:
pass
if __name__ == "__main__":
pytest.main([__file__, "-v"])