diff --git a/pyproject.toml b/pyproject.toml index bd3a40f..4d9f70f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,7 @@ classifiers = [ ] requires-python = ">=3.10" dependencies = [ + "ahe>=0.1.0", "matplotlib>=3.5.0", "numpy>=1.22, <3", "rlic>=0.2.1", diff --git a/src/lick/_image_processing.py b/src/lick/_image_processing.py index a8f21a0..c410d17 100644 --- a/src/lick/_image_processing.py +++ b/src/lick/_image_processing.py @@ -53,43 +53,9 @@ class HistogramEqualizer: nbins: int def process(self, image: FArray2D[F]) -> FArray2D[F]: - # adapted from scikit-image - """Return image after histogram equalization. - - Parameters - ---------- - image : array - Image array. - - Returns - ------- - out : float array - Image array after histogram equalization. - - Notes - ----- - This function is adapted from [1]_ with the author's permission. - - References - ---------- - .. [1] http://www.janeriksolem.net/histogram-equalization-with-python-and.html - .. [2] https://en.wikipedia.org/wiki/Histogram_equalization - - """ - import numpy as np - - hist, bin_edges = np.histogram(image.ravel(), bins=self.nbins) - bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2.0 - - cdf = hist.cumsum() - cdf = cdf / float(cdf[-1]) - - cdf = cdf.astype(image.dtype, copy=False) - out = np.interp(image.flat, bin_centers, cdf) - out = out.reshape(image.shape) - # Unfortunately, np.interp currently always promotes to float64, so we - # have to cast back to single precision when float32 output is desired - return out.astype(image.dtype, copy=False) # type: ignore[no-any-return] + import ahe + + return ahe.equalize_histogram(image, nbins=self.nbins) class LayeringMode(Enum): diff --git a/uv.lock b/uv.lock index 45a8743..faf99ad 100644 --- a/uv.lock +++ b/uv.lock @@ -14,6 +14,27 @@ constraints = [ ] build-constraints = [{ name = "setuptools", specifier = ">=61.0.0" }] +[[package]] +name = "ahe" +version = "0.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/8b/4907f351ef14acef86dc2a62da70904dc50ffba05469276bf06375dff35c/ahe-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:6e2bf7b597d04c540c686f7acdf2bc2645d75ecc95f484f93a5ed75c5d1cd7dc", size = 233182, upload-time = "2026-01-27T15:46:42.133Z" }, + { url = "https://files.pythonhosted.org/packages/72/97/7f79539786f571b01f29e080eec71fc9730e8f112deac666b0045880fb51/ahe-0.1.0-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:6a016593b55fa9da72edccb9ace4ab606c004addd999ee575d35d44dbf875fb0", size = 221794, upload-time = "2026-01-27T15:46:43.975Z" }, + { url = "https://files.pythonhosted.org/packages/6b/23/c54c7956fc63c83a65a91e3ee89596a8a09e8941007d7094d98a8fcbdb3d/ahe-0.1.0-cp310-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f73a6082cdc3ff6d512eef9aa26e0577c9dbb95a4461506bd27d06e66df791b1", size = 242320, upload-time = "2026-01-27T15:46:46.911Z" }, + { url = "https://files.pythonhosted.org/packages/ea/bb/f495887b826e98ea78fae8cddb8373862d5240359e645f0330da40b8a2fa/ahe-0.1.0-cp310-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:7765e88d686121ac77662974582bde1417934d0c47fc4f8f94e8b9c40302ffc7", size = 255046, upload-time = "2026-01-27T15:46:48.386Z" }, + { url = "https://files.pythonhosted.org/packages/4f/dd/2c7037cd635149956b8754040bb035efc662454b9b7e0d5c1969bcd58b3e/ahe-0.1.0-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:122a4bb222064773ec2feb4ffd886c307d3ea48fc0f7890fed8f93171f4457be", size = 425434, upload-time = "2026-01-27T15:46:50.019Z" }, + { url = "https://files.pythonhosted.org/packages/3a/40/92e3e462548deb1e167f6e4f57cfb9d2be9554bb48853a4fef917205d2f2/ahe-0.1.0-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4fab4ea9a195abe9efdf2af8905dca72293d6aecb5b60b6bc73dc5df4f11ca84", size = 467587, upload-time = "2026-01-27T15:46:51.878Z" }, + { url = "https://files.pythonhosted.org/packages/ee/bd/e6cad012e5dfa3a283778572ca99c2c1533cd7b1071e2b78e705a076765a/ahe-0.1.0-cp310-abi3-win32.whl", hash = "sha256:3773381c0b043294df045d16c7ed0c53c57c468d2fd69a43c3991e3ba00a3080", size = 144494, upload-time = "2026-01-27T15:46:53.262Z" }, + { url = "https://files.pythonhosted.org/packages/dd/f5/19515a1188c7512576abafe3a4b30ba7b7aa67a8f8b2cfb508bf5ff35ec7/ahe-0.1.0-cp310-abi3-win_amd64.whl", hash = "sha256:d3edea04d8348db14e7dff505f289ae7a9504fd88291561b0e6923e0d140ac24", size = 152169, upload-time = "2026-01-27T15:46:54.66Z" }, +] + [[package]] name = "colorama" version = "0.4.6" @@ -567,6 +588,7 @@ name = "lick" version = "0.9.0" source = { editable = "." } dependencies = [ + { name = "ahe" }, { name = "matplotlib" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, @@ -591,6 +613,7 @@ typecheck = [ [package.metadata] requires-dist = [ + { name = "ahe", specifier = ">=0.1.0" }, { name = "matplotlib", specifier = ">=3.5.0" }, { name = "numpy", specifier = ">=1.22,<3" }, { name = "rlic", specifier = ">=0.2.1" },