Source code for owl.mcam_data._color


import xarray as xr
# Not exactly part of the public API, but they seem to be open to it?
# https://github.com/pydata/xarray/issues/5081
from xarray.core.indexing import LazilyIndexedArray

from ..array._bayer2rgb_array import BayerToGrayArray, RGBToGrayArray
from ._properties import get_bayer_pattern, get_chroma


def _define_starting_index(bayer_pattern, channel):
    # channel should be a string of
    # 'red', 'green', or 'blue'
    if channel == 'green1':
        index = bayer_pattern.rfind(channel[0])
    else:
        index = bayer_pattern.find(channel[0])
    return (index // 2, index % 2)


[docs] def bayer_dataset_to_single_channel(dataset, color): """Extract a fixed color pixel from data acquired with CFA sensors. Given data acquired with a sensor contained a color filter array, this function extracts a single monochrome pixel from the array. This function can help reduce the data analysis load and speed up algorithms that work will with monochromatic images. While a standard Bayer pattern has one red pixel, and one blue pixel, it contains two green pixels. We denote the green pixel on the first row as the ``'green0'`` pixel, and the green pixel on the second row as the ``'green1'`` pixel. Here ``'green'`` is shorthand for ``'green0'``. Parameters ---------- dataset: mcam_dataset Dataset containing MCAM images. The dataset must contain the ``bayer_pattern`` that describes the pixel ordering in the color filter array. color: Color to extract. Must be one of: ``['red', 'green', 'blue', 'green0', 'green1']`` Returns ------- dataset: The returned dataset no longer contains the ``bayer_pattern`` variable to indicate that it has been converted to that of a monochromatic image. Notes ----- The images in the dataset must all have been acquired with the same pattern for the color filter array. """ from ._properties import get_bayer_pattern allowed_colors = ['red', 'green', 'blue', 'green0', 'green1'] if color not in allowed_colors: raise ValueError(f"Color must be in {allowed_colors}. Got {color}.") bayer_pattern = get_bayer_pattern(dataset) y_start, x_start = _define_starting_index(bayer_pattern, color) # drop creates a shallow copy dataset = dataset.drop_vars('bayer_pattern') dataset = dataset.isel({'y': slice(y_start, None, 2), 'x': slice(x_start, None, 2)}) return dataset
[docs] def bayer_dataset_to_rgb(dataset): """Convert a dataset acquired with a bayer sensor to an RGB dataset. Given data acquired with a sensor contained a color filter array, this converts the raw data to that of an RGB image. Parameters ---------- dataset: mcam_dataset Dataset containing MCAM images. The dataset must contain the ``bayer_pattern`` that describes the pixel ordering in the color filter array. The images variable will contain a new dimension labeled with `'rgb'` with dimension of 3. Returns ------- dataset: The returned dataset no longer contains the ``bayer_pattern`` variable to indicate that it has been converted to that of a monochromatic image. """ # TODO consolidate the methods: # * to_rgb # * bayer_dataset_to_rgb from ._core import to_rgb return to_rgb(dataset)
[docs] def bayer_dataset_to_grayscale(dataset, *, gray_vector=None): """Convert a dataset acquired with a bayer sensor to a grayscale dataset. Given data acquired with a sensor contained a color filter array, this converts the raw data to that of an RGB image. Parameters ---------- dataset: mcam_dataset Dataset containing MCAM images. The dataset must contain the ``bayer_pattern`` that describes the pixel ordering in the color filter array. The ``images`` variable will contain the new grayscale dataset. All other metadata will be retained. Returns ------- dataset: The returned dataset no longer contains the ``bayer_pattern`` variable to indicate that it has been converted to that of a monochromatic image. """ # Before merging, lets make sure that we resolve # https://gitlab.com/ramonaoptics/mcam/python-owl/-/issues/137 if get_chroma(dataset) != "bayer": raise ValueError('Can only convert raw bayer data to grayscale.') bayer_pattern = get_bayer_pattern(dataset) # FastPath for opencv grayscale_data = BayerToGrayArray( dataset.images.variable, bayer_pattern, gray_vector=gray_vector, ) grayscale_data = LazilyIndexedArray(grayscale_data) images = xr.DataArray( data=grayscale_data, dims=dataset.images.dims, attrs=dataset.images.attrs.copy(), ) # Shallow copy to not mutate the user's data dataset = dataset.copy(deep=False) dataset['images'] = images if 'bayer_pattern' in dataset: # Removing the bayer pattern indicates that it is a color image??? del dataset['bayer_pattern'] return dataset
[docs] def rgb_dataset_to_grayscale(dataset, *, gray_vector=None): """Convert a debayered rgb dataset to a grayscale dataset. Parameters ---------- dataset: mcam_dataset Dataset containing MCAM images. The dataset must contain the dimension ``rgb``. The ``images`` variable will contain the new grayscale dataset. All other metadata will be retained. gray_vector: tuple A 3-tuple of floats that describes the weights of the red, green, and blue channels in the conversion to grayscale. The default values are the ITU-R BT.709-1 standard. Returns ------- dataset: The returned dataset no longer contains the ``rgb`` dimension indicating that it has been converted to that of a grayscale image. """ if get_chroma(dataset) != "rgb": raise ValueError('Can only convert RGB data to grayscale.') grayscale_data = RGBToGrayArray(dataset.images.variable, gray_vector=gray_vector) grayscale_data = LazilyIndexedArray(grayscale_data) new_dims = [d for d in dataset.images.dims if d != 'rgb'] new_attrs = [a for a in dataset.images.attrs if a != 'rgb'] images = xr.DataArray( data=grayscale_data, dims=new_dims, attrs=new_attrs, ) # Shallow copy to not mutate the user's data dataset = dataset.copy(deep=False).drop_dims('rgb') dataset['images'] = images return dataset