Skip to content

Visualizers

This section covers all the visualizer classes provided by ImgVisFeat.

Base Visualizer

imvf.Visualizer

Module for image visualization in the ImgVisFeat package.

This module contains the Visualizer class, which provides functionality for loading, processing, and displaying or saving visualized images. It supports various visualization parameters and options to enhance image representation for analysis and presentation purposes.

Classes:

Name Description
Visualizer

Main class for image visualization operations.

Visualizer

A class for visualizing images.

This class provides functionality to visualize images, with options to display them on screen or save them to a specified directory.

Attributes:

Name Type Description
params dict

Additional parameters for visualization.

Example

vis = Visualizer() vis.visualize('path/to/image.jpg', dst_root='output_folder')

Source code in src/imvf/Visualizer.py
class Visualizer:
    """A class for visualizing images.

    This class provides functionality to visualize images, with options
    to display them on screen or save them to a specified directory.

    Attributes:
        params (dict): Additional parameters for visualization.

    Example:
        >>> vis = Visualizer()
        >>> vis.visualize('path/to/image.jpg', dst_root='output_folder')
    """

    def __init__(self, **params: dict) -> None:
        """Initialize the Visualizer.

        Args:
            **params: Additional parameters for visualization.
                These can include color maps, scaling factors, etc.
        """
        self.color_channel_visualizer = ColorChannelVisualizer()
        self.hog_visualizer = HoGVisualizer()
        self.power_spectrum_visualizer = PowerSpectrumVisualizer()
        self.sift_visualizer = KeypointVisualizer("SIFT")
        self.akaze_visualizer = KeypointVisualizer("AKAZE")
        self.orb_visualizer = KeypointVisualizer("ORB")
        self.color_gradient_visualizer = ColorGradientVisualizer()
        self.gray_gradient_visualizer = GrayGradientVisualizer()
        self.lbp_visualizer = LBPVisualizer()

    def visualize(self, src_image_path: str) -> None:
        """Visualize the image.

        This method loads an image from the given path, applies any
        visualization parameters, and either displays the image or
        saves it to the specified destination.

        Args:
            src_image_path (str): Path to the source image file.

        Example:
            >>> visualizer = Visualizer()
            >>> visualizer.visualize('input.jpg', dst_root='output')
        """
        print(f"Visualizing {src_image_path}")
        self.check_image_assertions(src_image_path)
        name, _ = os.path.splitext(os.path.basename(src_image_path))
        image = cv2.imread(src_image_path).astype("uint8")
        color_channel_result = self.color_channel_visualizer(image)
        gradient_result = self.color_gradient_visualizer(image)
        gray_gradient_result = self.gray_gradient_visualizer(image)
        hog_result = self.hog_visualizer(image)
        power_spectrum_result = self.power_spectrum_visualizer(image)
        sift_result = self.sift_visualizer(image)
        akaze_result = self.akaze_visualizer(image)
        orb_result = self.orb_visualizer(image)
        lbp_result = self.lbp_visualizer(image)

        os.makedirs(name, exist_ok=True)
        dst_path = os.path.join(name, "%s.png")
        cv2.imwrite(dst_path % "original", image)
        cv2.imwrite(dst_path % "channel_blue", color_channel_result.blue)
        cv2.imwrite(dst_path % "channel_green", color_channel_result.green)
        cv2.imwrite(dst_path % "channel_red", color_channel_result.red)
        cv2.imwrite(dst_path % "color_gradient_x", gradient_result.gradient_x)
        cv2.imwrite(dst_path % "color_gradient_y", gradient_result.gradient_y)
        cv2.imwrite(dst_path % "color_gradient_xy", gradient_result.gradient_xy)
        cv2.imwrite(dst_path % "gray_gradient_x", gray_gradient_result.gradient_x)
        cv2.imwrite(dst_path % "gray_gradient_y", gray_gradient_result.gradient_y)
        cv2.imwrite(dst_path % "gray_gradient_xy", gray_gradient_result.gradient_xy)
        cv2.imwrite(dst_path % "hog", hog_result.hog)
        cv2.imwrite(dst_path % "power_spectrum", power_spectrum_result.power_spectrum)
        cv2.imwrite(dst_path % "keypoint_sift_position", sift_result.keypoint)
        cv2.imwrite(dst_path % "keypoint_sift_rich", sift_result.rich_keypoint)
        cv2.imwrite(dst_path % "keypoint_akaze_position", akaze_result.keypoint)
        cv2.imwrite(dst_path % "keypoint_akaze_rich", akaze_result.rich_keypoint)
        cv2.imwrite(dst_path % "keypoint_orb_position", orb_result.keypoint)
        cv2.imwrite(dst_path % "keypoint_orb_rich", orb_result.rich_keypoint)
        cv2.imwrite(dst_path % "lbp", lbp_result.lbp)

        cv2.imshow("Original", image)
        cv2.imshow("Blue Channel", color_channel_result.blue)
        cv2.imshow("Green Channel", color_channel_result.green)
        cv2.imshow("Red Channel", color_channel_result.red)
        cv2.imshow("Color Gradient X", gradient_result.gradient_x)
        cv2.imshow("Color Gradient Y", gradient_result.gradient_y)
        cv2.imshow("Color Gradient X and Y", gradient_result.gradient_xy)
        cv2.imshow("Gray Gradient X", gray_gradient_result.gradient_x)
        cv2.imshow("Gray Gradient Y", gray_gradient_result.gradient_y)
        cv2.imshow("Gray Gradient X and Y", gray_gradient_result.gradient_xy)
        cv2.imshow("HoG", hog_result.hog)
        cv2.imshow("Power Spectrum", power_spectrum_result.power_spectrum)
        cv2.imshow("SIFT keypoint", sift_result.keypoint)
        cv2.imshow("SIFT rich keypoint", sift_result.rich_keypoint)
        cv2.imshow("AKAZE keypoint", akaze_result.keypoint)
        cv2.imshow("AKAZE rich keypoint", akaze_result.rich_keypoint)
        cv2.imshow("ORB keypoint", orb_result.keypoint)
        cv2.imshow("ORB rich keypoint", orb_result.rich_keypoint)
        cv2.imshow("LBP", lbp_result.lbp)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

    def check_image_assertions(self, src_image_path: str) -> None:
        """Check if the image path is valid.

        Args:
            src_image_path (str): Path to the image.

        Raises:
            FileNotFoundError: If the image is not found.
            IsADirectoryError: If the image path is not a file.
            ValueError: If the image path is not a image.
        """
        if not os.path.exists(src_image_path):
            raise FileNotFoundError(f"Image not found: {src_image_path}")
        elif not os.path.isfile(src_image_path):
            raise IsADirectoryError(
                f"Image path must be a file, but got {src_image_path}"
            )
        try:
            image = cv2.imread(src_image_path)
            _ = image.shape
        except AttributeError:
            raise ValueError(f"Image not found: {src_image_path}")
__init__
__init__(**params: dict) -> None

Initialize the Visualizer.

Parameters:

Name Type Description Default
**params dict

Additional parameters for visualization. These can include color maps, scaling factors, etc.

{}
Source code in src/imvf/Visualizer.py
def __init__(self, **params: dict) -> None:
    """Initialize the Visualizer.

    Args:
        **params: Additional parameters for visualization.
            These can include color maps, scaling factors, etc.
    """
    self.color_channel_visualizer = ColorChannelVisualizer()
    self.hog_visualizer = HoGVisualizer()
    self.power_spectrum_visualizer = PowerSpectrumVisualizer()
    self.sift_visualizer = KeypointVisualizer("SIFT")
    self.akaze_visualizer = KeypointVisualizer("AKAZE")
    self.orb_visualizer = KeypointVisualizer("ORB")
    self.color_gradient_visualizer = ColorGradientVisualizer()
    self.gray_gradient_visualizer = GrayGradientVisualizer()
    self.lbp_visualizer = LBPVisualizer()
visualize
visualize(src_image_path: str) -> None

Visualize the image.

This method loads an image from the given path, applies any visualization parameters, and either displays the image or saves it to the specified destination.

Parameters:

Name Type Description Default
src_image_path str

Path to the source image file.

required
Example

visualizer = Visualizer() visualizer.visualize('input.jpg', dst_root='output')

Source code in src/imvf/Visualizer.py
def visualize(self, src_image_path: str) -> None:
    """Visualize the image.

    This method loads an image from the given path, applies any
    visualization parameters, and either displays the image or
    saves it to the specified destination.

    Args:
        src_image_path (str): Path to the source image file.

    Example:
        >>> visualizer = Visualizer()
        >>> visualizer.visualize('input.jpg', dst_root='output')
    """
    print(f"Visualizing {src_image_path}")
    self.check_image_assertions(src_image_path)
    name, _ = os.path.splitext(os.path.basename(src_image_path))
    image = cv2.imread(src_image_path).astype("uint8")
    color_channel_result = self.color_channel_visualizer(image)
    gradient_result = self.color_gradient_visualizer(image)
    gray_gradient_result = self.gray_gradient_visualizer(image)
    hog_result = self.hog_visualizer(image)
    power_spectrum_result = self.power_spectrum_visualizer(image)
    sift_result = self.sift_visualizer(image)
    akaze_result = self.akaze_visualizer(image)
    orb_result = self.orb_visualizer(image)
    lbp_result = self.lbp_visualizer(image)

    os.makedirs(name, exist_ok=True)
    dst_path = os.path.join(name, "%s.png")
    cv2.imwrite(dst_path % "original", image)
    cv2.imwrite(dst_path % "channel_blue", color_channel_result.blue)
    cv2.imwrite(dst_path % "channel_green", color_channel_result.green)
    cv2.imwrite(dst_path % "channel_red", color_channel_result.red)
    cv2.imwrite(dst_path % "color_gradient_x", gradient_result.gradient_x)
    cv2.imwrite(dst_path % "color_gradient_y", gradient_result.gradient_y)
    cv2.imwrite(dst_path % "color_gradient_xy", gradient_result.gradient_xy)
    cv2.imwrite(dst_path % "gray_gradient_x", gray_gradient_result.gradient_x)
    cv2.imwrite(dst_path % "gray_gradient_y", gray_gradient_result.gradient_y)
    cv2.imwrite(dst_path % "gray_gradient_xy", gray_gradient_result.gradient_xy)
    cv2.imwrite(dst_path % "hog", hog_result.hog)
    cv2.imwrite(dst_path % "power_spectrum", power_spectrum_result.power_spectrum)
    cv2.imwrite(dst_path % "keypoint_sift_position", sift_result.keypoint)
    cv2.imwrite(dst_path % "keypoint_sift_rich", sift_result.rich_keypoint)
    cv2.imwrite(dst_path % "keypoint_akaze_position", akaze_result.keypoint)
    cv2.imwrite(dst_path % "keypoint_akaze_rich", akaze_result.rich_keypoint)
    cv2.imwrite(dst_path % "keypoint_orb_position", orb_result.keypoint)
    cv2.imwrite(dst_path % "keypoint_orb_rich", orb_result.rich_keypoint)
    cv2.imwrite(dst_path % "lbp", lbp_result.lbp)

    cv2.imshow("Original", image)
    cv2.imshow("Blue Channel", color_channel_result.blue)
    cv2.imshow("Green Channel", color_channel_result.green)
    cv2.imshow("Red Channel", color_channel_result.red)
    cv2.imshow("Color Gradient X", gradient_result.gradient_x)
    cv2.imshow("Color Gradient Y", gradient_result.gradient_y)
    cv2.imshow("Color Gradient X and Y", gradient_result.gradient_xy)
    cv2.imshow("Gray Gradient X", gray_gradient_result.gradient_x)
    cv2.imshow("Gray Gradient Y", gray_gradient_result.gradient_y)
    cv2.imshow("Gray Gradient X and Y", gray_gradient_result.gradient_xy)
    cv2.imshow("HoG", hog_result.hog)
    cv2.imshow("Power Spectrum", power_spectrum_result.power_spectrum)
    cv2.imshow("SIFT keypoint", sift_result.keypoint)
    cv2.imshow("SIFT rich keypoint", sift_result.rich_keypoint)
    cv2.imshow("AKAZE keypoint", akaze_result.keypoint)
    cv2.imshow("AKAZE rich keypoint", akaze_result.rich_keypoint)
    cv2.imshow("ORB keypoint", orb_result.keypoint)
    cv2.imshow("ORB rich keypoint", orb_result.rich_keypoint)
    cv2.imshow("LBP", lbp_result.lbp)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
check_image_assertions
check_image_assertions(src_image_path: str) -> None

Check if the image path is valid.

Parameters:

Name Type Description Default
src_image_path str

Path to the image.

required

Raises:

Type Description
FileNotFoundError

If the image is not found.

IsADirectoryError

If the image path is not a file.

ValueError

If the image path is not a image.

Source code in src/imvf/Visualizer.py
def check_image_assertions(self, src_image_path: str) -> None:
    """Check if the image path is valid.

    Args:
        src_image_path (str): Path to the image.

    Raises:
        FileNotFoundError: If the image is not found.
        IsADirectoryError: If the image path is not a file.
        ValueError: If the image path is not a image.
    """
    if not os.path.exists(src_image_path):
        raise FileNotFoundError(f"Image not found: {src_image_path}")
    elif not os.path.isfile(src_image_path):
        raise IsADirectoryError(
            f"Image path must be a file, but got {src_image_path}"
        )
    try:
        image = cv2.imread(src_image_path)
        _ = image.shape
    except AttributeError:
        raise ValueError(f"Image not found: {src_image_path}")

options: show_root_heading: true show_source: true

Color Channel Visualizer

imvf.ColorChannelVisualizer

ColorChannelVisualizer

Bases: AbstractVisualizer

A class for splitting the color channels of an image.

Source code in src/imvf/ColorChannelVisualizer.py
class ColorChannelVisualizer(AbstractVisualizer):
    """A class for splitting the color channels of an image."""

    def __init__(self) -> None:
        """Initialize the ColorChannelVisualizer class."""
        pass

    def __call__(self, source: NDArray[np.uint8]) -> ColorChannelResult:
        """Split the color channels of an image.

        Args:
            source (NDArray[np.uint8]): The source image.

        Returns:
            ColorChannelResult: The blue, green, and red color channels.
        """
        image = source.copy()
        if image.ndim != 3:
            image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR).astype(np.uint8)
        blue = np.zeros_like(image, dtype=np.uint8)
        green = np.zeros_like(image, dtype=np.uint8)
        red = np.zeros_like(image, dtype=np.uint8)
        blue[:, :, 0] = image[:, :, 0]
        green[:, :, 1] = image[:, :, 1]
        red[:, :, 2] = image[:, :, 2]
        return ColorChannelResult(blue=blue, green=green, red=red)
__init__
__init__() -> None

Initialize the ColorChannelVisualizer class.

Source code in src/imvf/ColorChannelVisualizer.py
def __init__(self) -> None:
    """Initialize the ColorChannelVisualizer class."""
    pass
__call__
__call__(source: NDArray[uint8]) -> ColorChannelResult

Split the color channels of an image.

Parameters:

Name Type Description Default
source NDArray[uint8]

The source image.

required

Returns:

Name Type Description
ColorChannelResult ColorChannelResult

The blue, green, and red color channels.

Source code in src/imvf/ColorChannelVisualizer.py
def __call__(self, source: NDArray[np.uint8]) -> ColorChannelResult:
    """Split the color channels of an image.

    Args:
        source (NDArray[np.uint8]): The source image.

    Returns:
        ColorChannelResult: The blue, green, and red color channels.
    """
    image = source.copy()
    if image.ndim != 3:
        image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR).astype(np.uint8)
    blue = np.zeros_like(image, dtype=np.uint8)
    green = np.zeros_like(image, dtype=np.uint8)
    red = np.zeros_like(image, dtype=np.uint8)
    blue[:, :, 0] = image[:, :, 0]
    green[:, :, 1] = image[:, :, 1]
    red[:, :, 2] = image[:, :, 2]
    return ColorChannelResult(blue=blue, green=green, red=red)

options: show_root_heading: true show_source: true

Gradient Visualizers

Color Gradient Visualizer

imvf.ColorGradientVisualizer

Bases: AbstractVisualizer

A class for computing the gradient of a color image.

Source code in src/imvf/GradientVisualizer.py
class ColorGradientVisualizer(AbstractVisualizer):
    """A class for computing the gradient of a color image."""

    def __init__(self) -> None:
        """Initialize the ColorGradientVisualizer class."""
        pass

    def __call__(self, source: NDArray[np.uint8]) -> GradientResult:
        """Compute the gradient of a color image.

        Args:
            source (NDArray[np.uint8]): The source image.

        Returns:
            GradientResult: The gradient in the x, y, and xy directions.
        """
        image = source.copy()
        if image.ndim != 3:
            image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR).astype(np.uint8)
        grad_x = np.zeros_like(image, dtype=np.uint8)
        grad_y = np.zeros_like(image, dtype=np.uint8)
        grad_xy = np.zeros_like(image, dtype=np.uint8)
        kernel_x = np.array([[0, 0, 0], [-1, 0, 1], [0, 0, 0]], np.float32)
        kernel_y = np.array([[0, 1, 0], [0, 0, 0], [0, -1, 0]], np.float32)
        kernel_xy = np.array([[0, 1, 0], [-1, 0, 1], [0, -1, 0]], np.float32)
        grad_x[:, :, 0] = cv2.filter2D(image[:, :, 0], -1, kernel_x).astype(np.uint8)
        grad_y[:, :, 0] = cv2.filter2D(image[:, :, 0], -1, kernel_y).astype(np.uint8)
        grad_xy[:, :, 0] = cv2.filter2D(image[:, :, 0], -1, kernel_xy).astype(np.uint8)
        grad_x[:, :, 1] = cv2.filter2D(image[:, :, 1], -1, kernel_x).astype(np.uint8)
        grad_y[:, :, 1] = cv2.filter2D(image[:, :, 1], -1, kernel_y).astype(np.uint8)
        grad_xy[:, :, 1] = cv2.filter2D(image[:, :, 1], -1, kernel_xy).astype(np.uint8)
        grad_x[:, :, 2] = cv2.filter2D(image[:, :, 2], -1, kernel_x).astype(np.uint8)
        grad_y[:, :, 2] = cv2.filter2D(image[:, :, 2], -1, kernel_y).astype(np.uint8)
        grad_xy[:, :, 2] = cv2.filter2D(image[:, :, 2], -1, kernel_xy).astype(np.uint8)
        return GradientResult(gradient_x=grad_x, gradient_y=grad_y, gradient_xy=grad_xy)

__init__

__init__() -> None

Initialize the ColorGradientVisualizer class.

Source code in src/imvf/GradientVisualizer.py
def __init__(self) -> None:
    """Initialize the ColorGradientVisualizer class."""
    pass

__call__

__call__(source: NDArray[uint8]) -> GradientResult

Compute the gradient of a color image.

Parameters:

Name Type Description Default
source NDArray[uint8]

The source image.

required

Returns:

Name Type Description
GradientResult GradientResult

The gradient in the x, y, and xy directions.

Source code in src/imvf/GradientVisualizer.py
def __call__(self, source: NDArray[np.uint8]) -> GradientResult:
    """Compute the gradient of a color image.

    Args:
        source (NDArray[np.uint8]): The source image.

    Returns:
        GradientResult: The gradient in the x, y, and xy directions.
    """
    image = source.copy()
    if image.ndim != 3:
        image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR).astype(np.uint8)
    grad_x = np.zeros_like(image, dtype=np.uint8)
    grad_y = np.zeros_like(image, dtype=np.uint8)
    grad_xy = np.zeros_like(image, dtype=np.uint8)
    kernel_x = np.array([[0, 0, 0], [-1, 0, 1], [0, 0, 0]], np.float32)
    kernel_y = np.array([[0, 1, 0], [0, 0, 0], [0, -1, 0]], np.float32)
    kernel_xy = np.array([[0, 1, 0], [-1, 0, 1], [0, -1, 0]], np.float32)
    grad_x[:, :, 0] = cv2.filter2D(image[:, :, 0], -1, kernel_x).astype(np.uint8)
    grad_y[:, :, 0] = cv2.filter2D(image[:, :, 0], -1, kernel_y).astype(np.uint8)
    grad_xy[:, :, 0] = cv2.filter2D(image[:, :, 0], -1, kernel_xy).astype(np.uint8)
    grad_x[:, :, 1] = cv2.filter2D(image[:, :, 1], -1, kernel_x).astype(np.uint8)
    grad_y[:, :, 1] = cv2.filter2D(image[:, :, 1], -1, kernel_y).astype(np.uint8)
    grad_xy[:, :, 1] = cv2.filter2D(image[:, :, 1], -1, kernel_xy).astype(np.uint8)
    grad_x[:, :, 2] = cv2.filter2D(image[:, :, 2], -1, kernel_x).astype(np.uint8)
    grad_y[:, :, 2] = cv2.filter2D(image[:, :, 2], -1, kernel_y).astype(np.uint8)
    grad_xy[:, :, 2] = cv2.filter2D(image[:, :, 2], -1, kernel_xy).astype(np.uint8)
    return GradientResult(gradient_x=grad_x, gradient_y=grad_y, gradient_xy=grad_xy)

options: show_root_heading: true show_source: true

Gray Gradient Visualizer

imvf.GrayGradientVisualizer

Bases: AbstractVisualizer

A class for computing the gradient of a grayscale image.

Source code in src/imvf/GradientVisualizer.py
class GrayGradientVisualizer(AbstractVisualizer):
    """A class for computing the gradient of a grayscale image."""

    def __init__(self) -> None:
        """Initialize the GrayGradientVisualizer class."""
        pass

    def __call__(self, source: NDArray[np.uint8]) -> GradientResult:
        """Compute the gradient of a grayscale image.

        Args:
            source (NDArray[np.uint8]): The source image.

        Returns:
            GradientResult: The gradient in the x, y, and xy directions.
        """
        if source.ndim != 2:
            gray = cv2.cvtColor(source, cv2.COLOR_BGR2GRAY).astype(np.uint8)
        else:
            gray = source.copy()
        kernel_x = np.array([[0, 0, 0], [-1, 0, 1], [0, 0, 0]], np.float32)
        kernel_y = np.array([[0, 1, 0], [0, 0, 0], [0, -1, 0]], np.float32)
        kernel_xy = np.array([[0, 1, 0], [-1, 0, 1], [0, -1, 0]], np.float32)
        grad_x = cv2.filter2D(gray, -1, kernel_x).astype(np.uint8)
        grad_y = cv2.filter2D(gray, -1, kernel_y).astype(np.uint8)
        grad_xy = cv2.filter2D(gray, -1, kernel_xy).astype(np.uint8)
        return GradientResult(gradient_x=grad_x, gradient_y=grad_y, gradient_xy=grad_xy)

__init__

__init__() -> None

Initialize the GrayGradientVisualizer class.

Source code in src/imvf/GradientVisualizer.py
def __init__(self) -> None:
    """Initialize the GrayGradientVisualizer class."""
    pass

__call__

__call__(source: NDArray[uint8]) -> GradientResult

Compute the gradient of a grayscale image.

Parameters:

Name Type Description Default
source NDArray[uint8]

The source image.

required

Returns:

Name Type Description
GradientResult GradientResult

The gradient in the x, y, and xy directions.

Source code in src/imvf/GradientVisualizer.py
def __call__(self, source: NDArray[np.uint8]) -> GradientResult:
    """Compute the gradient of a grayscale image.

    Args:
        source (NDArray[np.uint8]): The source image.

    Returns:
        GradientResult: The gradient in the x, y, and xy directions.
    """
    if source.ndim != 2:
        gray = cv2.cvtColor(source, cv2.COLOR_BGR2GRAY).astype(np.uint8)
    else:
        gray = source.copy()
    kernel_x = np.array([[0, 0, 0], [-1, 0, 1], [0, 0, 0]], np.float32)
    kernel_y = np.array([[0, 1, 0], [0, 0, 0], [0, -1, 0]], np.float32)
    kernel_xy = np.array([[0, 1, 0], [-1, 0, 1], [0, -1, 0]], np.float32)
    grad_x = cv2.filter2D(gray, -1, kernel_x).astype(np.uint8)
    grad_y = cv2.filter2D(gray, -1, kernel_y).astype(np.uint8)
    grad_xy = cv2.filter2D(gray, -1, kernel_xy).astype(np.uint8)
    return GradientResult(gradient_x=grad_x, gradient_y=grad_y, gradient_xy=grad_xy)

options: show_root_heading: true show_source: true

HoG Visualizer

imvf.HoGVisualizer

HoGVisualizer

Bases: AbstractVisualizer

A class for visualizing the HoG features of an image.

Source code in src/imvf/HoGVisualizer.py
class HoGVisualizer(AbstractVisualizer):
    """A class for visualizing the HoG features of an image."""

    def __init__(self) -> None:
        """Initialize the HoGVisualizer class."""
        pass

    def __call__(self, source: NDArray[np.uint8]) -> HogResult:
        """Compute the HoG features of an image.

        Args:
            source (NDArray[np.uint8]): The source image.

        Returns:
            HogResult: The HoG features of the image.
        """
        if source.ndim != 2:
            gray = cv2.cvtColor(source, cv2.COLOR_BGR2GRAY)
        else:
            gray = source.copy()
        _, hog_image = feature.hog(
            gray,
            orientations=9,
            pixels_per_cell=(16, 16),
            cells_per_block=(2, 2),
            block_norm="L2-Hys",
            visualize=True,
        )
        hog_image_uint8 = (hog_image * 255).astype(np.uint8)
        return HogResult(hog=hog_image_uint8)
__init__
__init__() -> None

Initialize the HoGVisualizer class.

Source code in src/imvf/HoGVisualizer.py
def __init__(self) -> None:
    """Initialize the HoGVisualizer class."""
    pass
__call__
__call__(source: NDArray[uint8]) -> HogResult

Compute the HoG features of an image.

Parameters:

Name Type Description Default
source NDArray[uint8]

The source image.

required

Returns:

Name Type Description
HogResult HogResult

The HoG features of the image.

Source code in src/imvf/HoGVisualizer.py
def __call__(self, source: NDArray[np.uint8]) -> HogResult:
    """Compute the HoG features of an image.

    Args:
        source (NDArray[np.uint8]): The source image.

    Returns:
        HogResult: The HoG features of the image.
    """
    if source.ndim != 2:
        gray = cv2.cvtColor(source, cv2.COLOR_BGR2GRAY)
    else:
        gray = source.copy()
    _, hog_image = feature.hog(
        gray,
        orientations=9,
        pixels_per_cell=(16, 16),
        cells_per_block=(2, 2),
        block_norm="L2-Hys",
        visualize=True,
    )
    hog_image_uint8 = (hog_image * 255).astype(np.uint8)
    return HogResult(hog=hog_image_uint8)

options: show_root_heading: true show_source: true

Keypoint Visualizer

imvf.KeypointVisualizer

KeypointVisualizer

Bases: AbstractVisualizer

A class for visualizing keypoints in an image.

Source code in src/imvf/KeypointVisualizer.py
class KeypointVisualizer(AbstractVisualizer):
    """A class for visualizing keypoints in an image."""

    def __init__(self, algorithm_name: str) -> None:
        """Initialize the KeypointVisualizer class."""
        if algorithm_name not in ["AKAZE", "SIFT", "ORB"]:
            raise ValueError(
                "Invalid algorithm name. Choose from 'AKAZE', 'SIFT', or 'ORB'."
            )
        self.algorithm_name = algorithm_name

    def __call__(self, source: NDArray[np.uint8]) -> KeypointResult:
        """Visualize keypoints in an image.

        Args:
            source (NDArray[np.uint8]): The source image.

        Returns:
            KeyPointResult: The image with keypoints and the image with rich keypoints.
        """
        color = source.copy()
        if source.ndim != 3:
            color = cv2.cvtColor(source, cv2.COLOR_GRAY2BGR).astype(np.uint8)
        if self.algorithm_name == "AKAZE":
            kp_image, rich_image = self.make_akaze_image(color)
        elif self.algorithm_name == "SIFT":
            kp_image, rich_image = self.make_sift_image(color)
        elif self.algorithm_name == "ORB":
            kp_image, rich_image = self.make_orb_image(color)
        else:
            raise ValueError(f"Invalid algorithm name: {self.algorithm_name}")
        return KeypointResult(keypoint=kp_image, rich_keypoint=rich_image)

    def make_akaze_image(
        self, color: NDArray[np.uint8]
    ) -> tuple[NDArray[np.uint8], NDArray[np.uint8]]:
        """Create an image with keypoints using the AKAZE algorithm.

        Args:
            color (NDArray[np.uint8]): The source image.

        Returns:
            tuple[NDArray[np.uint8], NDArray[np.uint8]]:
                The image with keypoints and the image with rich keypoints.
        """
        gray = cv2.cvtColor(color, cv2.COLOR_BGR2GRAY)
        kp_image = color.copy()
        rich_image = color.copy()
        detector = cv2.AKAZE_create()  # type: ignore
        keypoints = detector.detect(gray)
        circle_color = (255, 255, 0)
        for key in keypoints:
            cv2.circle(
                kp_image,
                (np.uint64(key.pt[0]), np.uint64(key.pt[1])),  # type: ignore
                3,
                circle_color,
                1,
            )
        cv2.drawKeypoints(
            rich_image,
            keypoints,
            rich_image,
            flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
        )
        print(f"Number of keypoints (AKAZE): {len(keypoints)}")
        return kp_image, rich_image

    def make_sift_image(
        self, color: NDArray[np.uint8]
    ) -> tuple[NDArray[np.uint8], NDArray[np.uint8]]:
        """Create an image with keypoints using the SIFT algorithm.

        Args:
            color (NDArray[np.uint8]): The source image.

        Returns:
            tuple[NDArray[np.uint8], NDArray[np.uint8]]:
                The image with keypoints and the image with rich keypoints.
        """
        gray = cv2.cvtColor(color, cv2.COLOR_BGR2GRAY)
        kp_image = color.copy()
        rich_image = color.copy()
        detector = cv2.SIFT_create()  # type: ignore
        keypoints = detector.detect(gray)
        circle_color = (255, 255, 0)
        for key in keypoints:
            cv2.circle(
                kp_image,
                (np.uint64(key.pt[0]), np.uint64(key.pt[1])),  # type: ignore
                3,
                circle_color,
                1,
            )
        cv2.drawKeypoints(
            rich_image,
            keypoints,
            rich_image,
            flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
        )
        print(f"Number of keypoints (SIFT) : {len(keypoints)}")
        return kp_image, rich_image

    def make_orb_image(
        self, color: NDArray[np.uint8]
    ) -> tuple[NDArray[np.uint8], NDArray[np.uint8]]:
        """Create an image with keypoints using the ORB algorithm.

        Args:
            color (NDArray[np.uint8]): The source image.

        Returns:
            tuple[NDArray[np.uint8], NDArray[np.uint8]]:
                The image with keypoints and the image with rich keypoints.
        """
        gray = cv2.cvtColor(color, cv2.COLOR_BGR2GRAY)
        kp_image = color.copy()
        rich_image = color.copy()
        detector = cv2.ORB_create()  # type: ignore
        keypoints = detector.detect(gray)
        circle_color = (255, 255, 0)
        cv2.drawKeypoints(kp_image, keypoints, kp_image, color=circle_color)
        cv2.drawKeypoints(
            rich_image,
            keypoints,
            rich_image,
            flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
        )
        print(f"Number of keypoints (ORB): {len(keypoints)}")
        return kp_image, rich_image

    def __str__(self) -> str:
        """Return the name of the visualizer.

        Returns:
            str: The name of the visualizer.
        """
        return f"{self.__class__.__name__}({self.algorithm_name})"
__init__
__init__(algorithm_name: str) -> None

Initialize the KeypointVisualizer class.

Source code in src/imvf/KeypointVisualizer.py
def __init__(self, algorithm_name: str) -> None:
    """Initialize the KeypointVisualizer class."""
    if algorithm_name not in ["AKAZE", "SIFT", "ORB"]:
        raise ValueError(
            "Invalid algorithm name. Choose from 'AKAZE', 'SIFT', or 'ORB'."
        )
    self.algorithm_name = algorithm_name
__call__
__call__(source: NDArray[uint8]) -> KeypointResult

Visualize keypoints in an image.

Parameters:

Name Type Description Default
source NDArray[uint8]

The source image.

required

Returns:

Name Type Description
KeyPointResult KeypointResult

The image with keypoints and the image with rich keypoints.

Source code in src/imvf/KeypointVisualizer.py
def __call__(self, source: NDArray[np.uint8]) -> KeypointResult:
    """Visualize keypoints in an image.

    Args:
        source (NDArray[np.uint8]): The source image.

    Returns:
        KeyPointResult: The image with keypoints and the image with rich keypoints.
    """
    color = source.copy()
    if source.ndim != 3:
        color = cv2.cvtColor(source, cv2.COLOR_GRAY2BGR).astype(np.uint8)
    if self.algorithm_name == "AKAZE":
        kp_image, rich_image = self.make_akaze_image(color)
    elif self.algorithm_name == "SIFT":
        kp_image, rich_image = self.make_sift_image(color)
    elif self.algorithm_name == "ORB":
        kp_image, rich_image = self.make_orb_image(color)
    else:
        raise ValueError(f"Invalid algorithm name: {self.algorithm_name}")
    return KeypointResult(keypoint=kp_image, rich_keypoint=rich_image)
make_akaze_image
make_akaze_image(color: NDArray[uint8]) -> tuple[NDArray[uint8], NDArray[uint8]]

Create an image with keypoints using the AKAZE algorithm.

Parameters:

Name Type Description Default
color NDArray[uint8]

The source image.

required

Returns:

Type Description
tuple[NDArray[uint8], NDArray[uint8]]

tuple[NDArray[np.uint8], NDArray[np.uint8]]: The image with keypoints and the image with rich keypoints.

Source code in src/imvf/KeypointVisualizer.py
def make_akaze_image(
    self, color: NDArray[np.uint8]
) -> tuple[NDArray[np.uint8], NDArray[np.uint8]]:
    """Create an image with keypoints using the AKAZE algorithm.

    Args:
        color (NDArray[np.uint8]): The source image.

    Returns:
        tuple[NDArray[np.uint8], NDArray[np.uint8]]:
            The image with keypoints and the image with rich keypoints.
    """
    gray = cv2.cvtColor(color, cv2.COLOR_BGR2GRAY)
    kp_image = color.copy()
    rich_image = color.copy()
    detector = cv2.AKAZE_create()  # type: ignore
    keypoints = detector.detect(gray)
    circle_color = (255, 255, 0)
    for key in keypoints:
        cv2.circle(
            kp_image,
            (np.uint64(key.pt[0]), np.uint64(key.pt[1])),  # type: ignore
            3,
            circle_color,
            1,
        )
    cv2.drawKeypoints(
        rich_image,
        keypoints,
        rich_image,
        flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
    )
    print(f"Number of keypoints (AKAZE): {len(keypoints)}")
    return kp_image, rich_image
make_sift_image
make_sift_image(color: NDArray[uint8]) -> tuple[NDArray[uint8], NDArray[uint8]]

Create an image with keypoints using the SIFT algorithm.

Parameters:

Name Type Description Default
color NDArray[uint8]

The source image.

required

Returns:

Type Description
tuple[NDArray[uint8], NDArray[uint8]]

tuple[NDArray[np.uint8], NDArray[np.uint8]]: The image with keypoints and the image with rich keypoints.

Source code in src/imvf/KeypointVisualizer.py
def make_sift_image(
    self, color: NDArray[np.uint8]
) -> tuple[NDArray[np.uint8], NDArray[np.uint8]]:
    """Create an image with keypoints using the SIFT algorithm.

    Args:
        color (NDArray[np.uint8]): The source image.

    Returns:
        tuple[NDArray[np.uint8], NDArray[np.uint8]]:
            The image with keypoints and the image with rich keypoints.
    """
    gray = cv2.cvtColor(color, cv2.COLOR_BGR2GRAY)
    kp_image = color.copy()
    rich_image = color.copy()
    detector = cv2.SIFT_create()  # type: ignore
    keypoints = detector.detect(gray)
    circle_color = (255, 255, 0)
    for key in keypoints:
        cv2.circle(
            kp_image,
            (np.uint64(key.pt[0]), np.uint64(key.pt[1])),  # type: ignore
            3,
            circle_color,
            1,
        )
    cv2.drawKeypoints(
        rich_image,
        keypoints,
        rich_image,
        flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
    )
    print(f"Number of keypoints (SIFT) : {len(keypoints)}")
    return kp_image, rich_image
make_orb_image
make_orb_image(color: NDArray[uint8]) -> tuple[NDArray[uint8], NDArray[uint8]]

Create an image with keypoints using the ORB algorithm.

Parameters:

Name Type Description Default
color NDArray[uint8]

The source image.

required

Returns:

Type Description
tuple[NDArray[uint8], NDArray[uint8]]

tuple[NDArray[np.uint8], NDArray[np.uint8]]: The image with keypoints and the image with rich keypoints.

Source code in src/imvf/KeypointVisualizer.py
def make_orb_image(
    self, color: NDArray[np.uint8]
) -> tuple[NDArray[np.uint8], NDArray[np.uint8]]:
    """Create an image with keypoints using the ORB algorithm.

    Args:
        color (NDArray[np.uint8]): The source image.

    Returns:
        tuple[NDArray[np.uint8], NDArray[np.uint8]]:
            The image with keypoints and the image with rich keypoints.
    """
    gray = cv2.cvtColor(color, cv2.COLOR_BGR2GRAY)
    kp_image = color.copy()
    rich_image = color.copy()
    detector = cv2.ORB_create()  # type: ignore
    keypoints = detector.detect(gray)
    circle_color = (255, 255, 0)
    cv2.drawKeypoints(kp_image, keypoints, kp_image, color=circle_color)
    cv2.drawKeypoints(
        rich_image,
        keypoints,
        rich_image,
        flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
    )
    print(f"Number of keypoints (ORB): {len(keypoints)}")
    return kp_image, rich_image
__str__
__str__() -> str

Return the name of the visualizer.

Returns:

Name Type Description
str str

The name of the visualizer.

Source code in src/imvf/KeypointVisualizer.py
def __str__(self) -> str:
    """Return the name of the visualizer.

    Returns:
        str: The name of the visualizer.
    """
    return f"{self.__class__.__name__}({self.algorithm_name})"

options: show_root_heading: true show_source: true

LBP Visualizer

imvf.LBPVisualizer

LBPVisualizer

Bases: AbstractVisualizer

A class for computing the Local Binary Pattern (LBP) of an image.

Source code in src/imvf/LBPVisualizer.py
class LBPVisualizer(AbstractVisualizer):
    """A class for computing the Local Binary Pattern (LBP) of an image."""

    def __init__(self) -> None:
        """Initialize the LBPVisualizer class."""
        pass

    def __call__(self, source: NDArray[np.uint8]) -> LBPResult:
        """Compute the Local Binary Pattern (LBP) of an image.

        Args:
            source (NDArray[np.uint8]): The source image.

        Returns:
            LBPResult: The LBP image.
        """
        if source.ndim != 2:
            gray = cv2.cvtColor(source, cv2.COLOR_BGR2GRAY)
        else:
            gray = source.copy()
        counter = 0
        lbp = 8 * [0]
        lbp_image = np.zeros((gray.shape[0] - 2, gray.shape[1] - 2), dtype=np.uint8)
        for centerY in range(1, gray.shape[0] - 1):
            for centerX in range(1, gray.shape[1] - 1):
                for yy in range(centerY - 1, centerY + 2):
                    for xx in range(centerX - 1, centerX + 2):
                        if (xx != centerX) or (yy != centerY):
                            if gray[centerY, centerX] >= gray[yy, xx]:
                                lbp[counter] = 0
                            else:
                                lbp[counter] = 1
                            counter += 1
                lbp_pix = (
                    lbp[0] * 2**7
                    + lbp[1] * 2**6
                    + lbp[2] * 2**5
                    + lbp[4] * 2**4
                    + lbp[7] * 2**3
                    + lbp[6] * 2**2
                    + lbp[5] * 2**1
                    + lbp[3] * 2**0
                )
                lbp_image[centerY - 1, centerX - 1] = lbp_pix
                counter = 0
        lbp_image = cv2.copyMakeBorder(  # type: ignore
            lbp_image, 1, 1, 1, 1, cv2.BORDER_CONSTANT, value=0
        )
        return LBPResult(lbp=lbp_image)
__init__
__init__() -> None

Initialize the LBPVisualizer class.

Source code in src/imvf/LBPVisualizer.py
def __init__(self) -> None:
    """Initialize the LBPVisualizer class."""
    pass
__call__
__call__(source: NDArray[uint8]) -> LBPResult

Compute the Local Binary Pattern (LBP) of an image.

Parameters:

Name Type Description Default
source NDArray[uint8]

The source image.

required

Returns:

Name Type Description
LBPResult LBPResult

The LBP image.

Source code in src/imvf/LBPVisualizer.py
def __call__(self, source: NDArray[np.uint8]) -> LBPResult:
    """Compute the Local Binary Pattern (LBP) of an image.

    Args:
        source (NDArray[np.uint8]): The source image.

    Returns:
        LBPResult: The LBP image.
    """
    if source.ndim != 2:
        gray = cv2.cvtColor(source, cv2.COLOR_BGR2GRAY)
    else:
        gray = source.copy()
    counter = 0
    lbp = 8 * [0]
    lbp_image = np.zeros((gray.shape[0] - 2, gray.shape[1] - 2), dtype=np.uint8)
    for centerY in range(1, gray.shape[0] - 1):
        for centerX in range(1, gray.shape[1] - 1):
            for yy in range(centerY - 1, centerY + 2):
                for xx in range(centerX - 1, centerX + 2):
                    if (xx != centerX) or (yy != centerY):
                        if gray[centerY, centerX] >= gray[yy, xx]:
                            lbp[counter] = 0
                        else:
                            lbp[counter] = 1
                        counter += 1
            lbp_pix = (
                lbp[0] * 2**7
                + lbp[1] * 2**6
                + lbp[2] * 2**5
                + lbp[4] * 2**4
                + lbp[7] * 2**3
                + lbp[6] * 2**2
                + lbp[5] * 2**1
                + lbp[3] * 2**0
            )
            lbp_image[centerY - 1, centerX - 1] = lbp_pix
            counter = 0
    lbp_image = cv2.copyMakeBorder(  # type: ignore
        lbp_image, 1, 1, 1, 1, cv2.BORDER_CONSTANT, value=0
    )
    return LBPResult(lbp=lbp_image)

options: show_root_heading: true show_source: true

Power Spectrum Visualizer

imvf.PowerSpectrumVisualizer

PowerSpectrumVisualizer

Bases: AbstractVisualizer

A class for computing the power spectrum of an image.

Source code in src/imvf/PowerSpectrumVisualizer.py
class PowerSpectrumVisualizer(AbstractVisualizer):
    """A class for computing the power spectrum of an image."""

    def __init__(self) -> None:
        """Initialize the PowerSpectrumVisualizer class."""
        pass

    def __call__(self, source: NDArray[np.uint8]) -> PowerSpectrumResult:
        """Compute the power spectrum of an image.

        Args:
            source (NDArray[np.uint8]): The source image.

        Returns:
            PowerSpectrumResult: The power spectrum of the image.
        """
        if source.ndim != 2:
            gray = cv2.cvtColor(source, cv2.COLOR_BGR2GRAY)
        else:
            gray = source.copy()
        gray = np.array(gray)
        fft = np.fft.fft2(gray)
        fft = np.fft.fftshift(fft)
        pow = np.abs(fft) ** 2
        pow = np.log10(pow)
        p_max = np.max(pow)
        pow = pow / p_max * 255
        pow_image = np.array(np.uint8(pow))

        return PowerSpectrumResult(power_spectrum=pow_image)
__init__
__init__() -> None

Initialize the PowerSpectrumVisualizer class.

Source code in src/imvf/PowerSpectrumVisualizer.py
def __init__(self) -> None:
    """Initialize the PowerSpectrumVisualizer class."""
    pass
__call__
__call__(source: NDArray[uint8]) -> PowerSpectrumResult

Compute the power spectrum of an image.

Parameters:

Name Type Description Default
source NDArray[uint8]

The source image.

required

Returns:

Name Type Description
PowerSpectrumResult PowerSpectrumResult

The power spectrum of the image.

Source code in src/imvf/PowerSpectrumVisualizer.py
def __call__(self, source: NDArray[np.uint8]) -> PowerSpectrumResult:
    """Compute the power spectrum of an image.

    Args:
        source (NDArray[np.uint8]): The source image.

    Returns:
        PowerSpectrumResult: The power spectrum of the image.
    """
    if source.ndim != 2:
        gray = cv2.cvtColor(source, cv2.COLOR_BGR2GRAY)
    else:
        gray = source.copy()
    gray = np.array(gray)
    fft = np.fft.fft2(gray)
    fft = np.fft.fftshift(fft)
    pow = np.abs(fft) ** 2
    pow = np.log10(pow)
    p_max = np.max(pow)
    pow = pow / p_max * 255
    pow_image = np.array(np.uint8(pow))

    return PowerSpectrumResult(power_spectrum=pow_image)

options: show_root_heading: true show_source: true