Source code for stouputils.data_science.data_processing.image.auto_contrast


# pyright: reportUnusedImport=false
# ruff: noqa: F401

# Imports
from .common import Any, NDArray, check_image, cv2, np


# Functions
[docs] def auto_contrast_image(image: NDArray[Any], ignore_dtype: bool = False) -> NDArray[Any]: """ Adjust the contrast of an image. Args: image (NDArray[Any]): Image to adjust contrast ignore_dtype (bool): Ignore the dtype check Returns: NDArray[Any]: Image with adjusted contrast >>> ## Basic tests >>> image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.uint8) >>> adjusted = auto_contrast_image(image) >>> adjusted.tolist() [[0, 36, 73], [109, 146, 182], [219, 255, 255]] >>> adjusted.shape == image.shape True >>> adjusted.dtype == image.dtype True >>> ## Test invalid inputs >>> auto_contrast_image("not an image") Traceback (most recent call last): ... AssertionError: Image must be a numpy array """ # Check input data check_image(image, ignore_dtype=ignore_dtype) # Perform histogram clipping clip_hist_percent: float = 1.0 # Calculate the histogram of the image hist: NDArray[Any] = cv2.calcHist([image], [0], None, [256], [0, 256]) # Create an accumulator list to store the cumulative histogram accumulator: list[float] = [] accumulator.append(hist[0]) for i in range(1, 256): accumulator.append(accumulator[i - 1] + hist[i]) # Find the maximum value in the accumulator max_value: float = accumulator[-1] # Calculate the clipping threshold clip_hist_percent = clip_hist_percent * (max_value / 100.0) clip_hist_percent = clip_hist_percent / 2.0 # Find the minimum and maximum gray levels after clipping min_gray: int = 0 while accumulator[min_gray] < clip_hist_percent: min_gray = min_gray + 1 max_gray: int = 256 - 1 while (max_gray >= 0 and accumulator[max_gray] >= (max_value - clip_hist_percent)): max_gray = max_gray - 1 # Calculate the input range after clipping input_range: int = max_gray - min_gray # If the input range is 0, return the original image if input_range == 0: return image # Calculate the scaling factors for contrast adjustment alpha: float = (256 - 1) / input_range beta: float = -min_gray * alpha # Apply the contrast adjustment adjusted: NDArray[Any] = cv2.convertScaleAbs(image, alpha=alpha, beta=beta) return adjusted