Source code for draugr.opencv_utilities.color_space.gray
from enum import Enum
import cv2
from sorcery import assigned_names
from draugr.opencv_utilities.color_space.color import is_singular_channel
from draugr.opencv_utilities.namespaces.color_conversion_enum import (
ColorConversionEnum,
)
__all__ = ["ToGrayMethodEnum", "to_gray"]
[docs]class ToGrayMethodEnum(Enum):
gray, rgb, hsv, ycrcb, yuv, lab, luv = assigned_names()
[docs]def to_gray(
image,
*,
component: int = 0,
to_gray_method: ToGrayMethodEnum = ToGrayMethodEnum.gray
):
"""
convert from the default bgr cv2 format to gray, using a single component
:param image:
:type image:
:param component:
:type component:
:param to_gray_method:
:type to_gray_method:
:return:
:rtype:
"""
if not is_singular_channel(image):
to_gray_method = ToGrayMethodEnum(to_gray_method)
if to_gray_method == to_gray_method.gray:
# Weighted sum of the three channels
# 0.299*R + 0.587*G + 0.114*B
components = (cv2.cvtColor(image, ColorConversionEnum.bgr2gray.value),)
elif to_gray_method == ToGrayMethodEnum.rgb: # Red Green Blue
# Pick a single channel
components = cv2.split(
cv2.cvtColor(image, ColorConversionEnum.bgr2rgb.value)
)
elif (
to_gray_method == ToGrayMethodEnum.hsv
): # Hue ( Dominant Wavelength ) S – Saturation ( Purity / shades of the color ) V – Value ( Intensity )
# The H Component is very similar in both the images which indicates the color information is intact even under illumination changes.
# The S component is also very similar in both images.
# The V Component captures the amount of light falling on it thus it changes due to illumination changes.
# There is drastic difference between the values of the red piece of outdoor and Indoor image. This is because Hue is represented as a circle and red is at the starting angle. So, it may take values between [300, 360] and again [0, 60].
components = cv2.split(
cv2.cvtColor(image, ColorConversionEnum.bgr2hsv.value)
)
elif (
to_gray_method == ToGrayMethodEnum.ycrcb
): # Y – Luma ( Luminance ) Cb – Chroma Blue ( Color ) Cr – Chroma Red ( Color )
# Y – Luminance or Luma component obtained from RGB after gamma correction.
# Cr = R – Y ( how far is the red component from Luma ).
# Cb = B – Y ( how far is the blue component from Luma ).
# Similar observations as LAB can be made for Intensity and color components with regard to Illumination changes.
# Perceptual difference between Red and Orange is less even in the outdoor image as compared to LAB.
# White has undergone change in all 3 components.
components = cv2.split(
cv2.cvtColor(image, ColorConversionEnum.bgr2ycrcb.value)
)
elif to_gray_method == ToGrayMethodEnum.yuv:
# Y, a measure of overall brightness or luminance. U and V are computed as scaled differences between Y′ and the B and R values.
components = cv2.split(
cv2.cvtColor(image, ColorConversionEnum.bgr2yuv.value)
)
elif (
to_gray_method == to_gray_method.lab
): # L – Lightness ( Brightness ) a – Green-Magenta ( Green - Red ) b – Blue-Yellow ( Blue - Red )
# Illumination has mostly affected the L component.
# The A and B components which contain the color information did not undergo massive changes.
# The respective values of Green, Orange and Red ( which are the extremes of the A Component ) has not changed in the B Component and similarly the respective values of Blue and Yellow ( which are the extremes of the B Component ) has not changed in the A component.
components = cv2.split(
cv2.cvtColor(image, ColorConversionEnum.bgr2lab.value)
)
elif to_gray_method == to_gray_method.luv:
# LUV decouple the "color" (chromaticity, the UV part) and "lightness" (luminance, the L part)
components = cv2.split(
cv2.cvtColor(image, ColorConversionEnum.bgr2luv.value)
)
else:
raise NotImplementedError
return components[component]
return image