Source code for medical_image.algorithms.FEBDS

import torch
from medical_image.algorithms.algorithm import Algorithm
from medical_image.data.image import Image
from medical_image.data.in_memory_image import InMemoryImage
from medical_image.process.filters import Filters
from medical_image.process.frequency import FrequencyOperations
from medical_image.process.morphology import MorphologyOperations
from medical_image.process.threshold import Threshold
from medical_image.utils.image_utils import MathematicalOperations


[docs] class FebdsAlgorithm(Algorithm): """ Fourier Enhancement and Band-pass Filtering Algorithm for Microcalcification Segmentation. References:: @article{article, author = {Lopez, Elizabeth and Urcid, Gonzalo}, year = {2016}, month = {05}, pages = {}, title = {Mammograms calcifications segmentation based on band-pass Fourier filtering and adaptive statistical thresholding}, volume = {5} } Math and Logic: This algorithm aims to enhance microcalcifications by highlighting high-frequency components while removing noise and low-frequency background signals. It supports filtering in the spatial domain using Difference of Gaussians (DoG) or Laplacian of Gaussian (LoG), or in the frequency domain using a Fast Fourier Transform (FFT) with a Butterworth band-pass filter. After enhancement, the image is denoised via median filtering and gamma correction is applied to amplify the calcifications, followed by adaptive thresholding (like Otsu's) or binarization, and morphological closing to reconstruct regions. Pipeline: 1. Apply base enhancement filter depending on the method (``dog``, ``log``, ``fft``). 2. Denoise and smooth by taking the absolute value and applying a median filter. 3. Apply gamma correction to increase the contrast of microcalcifications. 4. Apply global thresholding (binarize for ``fft``, Otsu for ``dog``/``log``). 5. Apply morphological closing and region filling to restore shape and connectivity. Example:: from medical_image.algorithms.FEBDS import FebdsAlgorithm from medical_image.data.dicom_image import DicomImage img = DicomImage("20527054.dcm") img.load() algo = FebdsAlgorithm(method="dog", device="cpu") output = img.clone() algo(img, output) """
[docs] def __init__(self, method: str, device: str = "cpu"): super().__init__(device=device) self.method = method # Filters self.dog = lambda img, out: Filters.difference_of_gaussian( image=img, output=out, low_sigma=1.7, high_sigma=2.0, device=self.device, ) self.log = lambda img, out: Filters.laplacian_of_gaussian( image=img, output=out, sigma=2.0, device=self.device ) self.median = lambda img, out: Filters.median_filter( image=img, output=out, size=5, device=self.device ) self.gamma = lambda img, out: Filters.gamma_correction( image=img, output=out, gamma=1.25, device=self.device ) self.abs = lambda img, out: MathematicalOperations.abs(image=img, out=out) # Frequency domain self.fft = lambda img, out: FrequencyOperations.fft( image=img, output=out, device=self.device ) self.inverse_fft = lambda img, out: FrequencyOperations.inverse_fft( image=img, output=out, device=self.device ) self.butter_kernel = lambda img, out: Filters.butterworth_kernel( image=img, output=out, device=self.device ) # Thresholds self.binarize = lambda img, out: Threshold.binarize( image=img, output=out, alpha=1, device=self.device ) self.otsu = lambda img, out: Threshold.otsu_threshold( image=img, output=out, device=self.device ) # Morphology self.morphology_closing = ( lambda img, out: MorphologyOperations.morphology_closing( image=img, output=out, device=self.device ) ) self.region_fill = lambda img, out: MorphologyOperations.region_fill( image=img, output=out, device=self.device )
[docs] def apply(self, image: Image, output: Image) -> Image: """Applies the selected method pipeline in-place on output.""" # Step 1: Base filter if self.method == "dog": self.dog(image, output) elif self.method == "log": self.log(image, output) elif self.method == "fft": self.fft(image, output) # Frequency band-pass with Butterworth kernel kernel_img = InMemoryImage(array=torch.zeros_like(output.pixel_data)) self.butter_kernel(output, kernel_img) output.pixel_data *= kernel_img.pixel_data self.inverse_fft(output, output) # Step 2: Denoise and smoothing self.abs(output, output) self.median(output, output) # Step 3: Gamma correction self.gamma(output, output) # Step 4: Thresholding if self.method == "fft": self.binarize(output, output) else: self.otsu(output, output) # Step 5: Morphological post-processing self.morphology_closing(output, output) self.region_fill(output, output) return output