Source code for aws.osml.gdal.dynamic_range_adjustment

#  Copyright 2023-2024 Amazon.com, Inc. or its affiliates.

from typing import List, Optional


[docs] class DRAParameters: """ This class manages a set of parameters used to perform a Dynamic Range Adjustment that is applied when converting imagery pixel values (e.g. 11-bit per pixel panchromatic imagery to an 8-bit per pixel grayscale). """ def __init__( self, suggested_min_value: float, suggested_max_value: float, actual_min_value: float, actual_max_value: float ): """ Constructor for this class. :param suggested_min_value: suggested minimum value of the relevant pixel range :param suggested_max_value: suggested maximum value of the relevant pixel range :param actual_min_value: actual minimum value of pixels in the image :param actual_max_value: actual maximum value of pixels in the image """ self.suggested_min_value = suggested_min_value self.suggested_max_value = suggested_max_value self.actual_min_value = actual_min_value self.actual_max_value = actual_max_value
[docs] @staticmethod def from_counts( counts: List[float], first_bucket_value: Optional[float] = None, last_bucket_value: Optional[float] = None, min_percentage: float = 0.02, max_percentage: float = 0.98, a: float = 0.2, b: float = 0.4, ) -> "DRAParameters": """ This static factory method computes a new set of DRA parameters given a histogram of pixel values. :param counts: histogram of the pixel values :param first_bucket_value: pixel value of the first bucket, defaults to 0 :param last_bucket_value: pixel value of the last bucket, defaults to bucket index :param min_percentage: set point for low intensity pixels that may be outliers :param max_percentage: set point for high intensity pixels that may be outliers :param a: weighting factor for the low intensity range :param b: weighting factor for the high intensity range :return: a set of DRA parameters containing recommended and actual ranges of values """ num_histogram_bins = len(counts) if not first_bucket_value: first_bucket_value = 0 if not last_bucket_value: last_bucket_value = num_histogram_bins # Find the first and last non-zero counts actual_min_value = 0 while actual_min_value < num_histogram_bins and counts[actual_min_value] == 0: actual_min_value += 1 actual_max_value = num_histogram_bins - 1 while actual_max_value > 0 and counts[actual_max_value] == 0: actual_max_value -= 1 # Compute the cumulative distribution cumulative_counts = counts.copy() for i in range(1, len(cumulative_counts)): cumulative_counts[i] = cumulative_counts[i] + cumulative_counts[i - 1] # Find the values that exclude the lowest and highest percentages of the counts. # This identifies the range that contains most of the pixels while excluding outliers. max_counts = cumulative_counts[-1] low_threshold = min_percentage * max_counts e_min = 0 while cumulative_counts[e_min] < low_threshold and e_min < len(cumulative_counts) - 1: e_min += 1 high_threshold = max_percentage * max_counts e_max = num_histogram_bins - 1 while cumulative_counts[e_max] > high_threshold and e_max > 0: e_max -= 1 min_value = max([actual_min_value, e_min - a * (e_max - e_min)]) max_value = min([actual_max_value, e_max + b * (e_max - e_min)]) value_step = (last_bucket_value - first_bucket_value) / num_histogram_bins return DRAParameters( suggested_min_value=min_value * value_step + first_bucket_value, suggested_max_value=max_value * value_step + first_bucket_value, actual_min_value=actual_min_value * value_step + first_bucket_value, actual_max_value=actual_max_value * value_step + first_bucket_value, )
def __repr__(self): return ( f"DRAParameters(min_value={self.suggested_min_value}, " f"max_value={self.suggested_max_value}, " f"e_first={self.actual_min_value}, " f"e_last={self.actual_max_value}, " f")" )