AI_Lab_CAM / cv_ops /morphology.py
Aditya7864's picture
Add application file
8096125
Raw
History Blame Contribute Delete
1.81 kB
"""Morphological image operations."""
from __future__ import annotations
import cv2
import numpy as np
from filters.builtin import ensure_rgb
SHAPES = {"rect": cv2.MORPH_RECT, "ellipse": cv2.MORPH_ELLIPSE, "cross": cv2.MORPH_CROSS}
OPS = {
"Erosion": cv2.MORPH_ERODE,
"Dilation": cv2.MORPH_DILATE,
"Opening": cv2.MORPH_OPEN,
"Closing": cv2.MORPH_CLOSE,
"Gradient": cv2.MORPH_GRADIENT,
"Top-Hat": cv2.MORPH_TOPHAT,
"Black-Hat": cv2.MORPH_BLACKHAT,
}
def make_kernel(shape: str = "rect", size: int = 5) -> np.ndarray:
size = max(1, int(size))
if size % 2 == 0:
size += 1
return cv2.getStructuringElement(SHAPES.get(shape, cv2.MORPH_RECT), (size, size))
def threshold_image(image: np.ndarray, method: str = "Otsu", threshold: int = 128) -> np.ndarray:
gray = cv2.cvtColor(ensure_rgb(image), cv2.COLOR_RGB2GRAY)
if method == "Otsu":
_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
else:
_, binary = cv2.threshold(gray, int(threshold), 255, cv2.THRESH_BINARY)
return binary
def apply_morphology(image: np.ndarray, operation: str = "Opening", shape: str = "rect", size: int = 5, iterations: int = 1, threshold_method: str = "Otsu", threshold: int = 128) -> tuple[np.ndarray, np.ndarray]:
binary = threshold_image(image, threshold_method, threshold)
kernel = make_kernel(shape, size)
op = OPS.get(operation, cv2.MORPH_OPEN)
if op == cv2.MORPH_ERODE:
result = cv2.erode(binary, kernel, iterations=int(iterations))
elif op == cv2.MORPH_DILATE:
result = cv2.dilate(binary, kernel, iterations=int(iterations))
else:
result = cv2.morphologyEx(binary, op, kernel, iterations=int(iterations))
return cv2.cvtColor(result, cv2.COLOR_GRAY2RGB), kernel