diff --git a/.gitignore b/.gitignore
index 6acf99ddd141ad1b3f5df7ed086840fe8074a5a6..d0990d6dc47420c48da2cf26392051f02c7f5d06 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,6 @@ build/
 
 # Notebook checkpoints
 .ipynb_checkpoints/
+
+# MacOS finder files
+*.DS_Store
\ No newline at end of file
diff --git a/docs/assets/screenshots/operations-remove_background_after.png b/docs/assets/screenshots/operations-remove_background_after.png
new file mode 100644
index 0000000000000000000000000000000000000000..0148a8f65a770f6707fa7264ad41a0c30ecbfac0
Binary files /dev/null and b/docs/assets/screenshots/operations-remove_background_after.png differ
diff --git a/docs/assets/screenshots/operations-remove_background_before.png b/docs/assets/screenshots/operations-remove_background_before.png
new file mode 100644
index 0000000000000000000000000000000000000000..e4c63b94598b763df56075475bf0e09ce4ff7970
Binary files /dev/null and b/docs/assets/screenshots/operations-remove_background_before.png differ
diff --git a/docs/processing.md b/docs/processing.md
index b469a21c6bf8cf1c9115e9efa0f9404dd62c9b53..2987f9f74c493a2032cbba95c903db2cc2fa056a 100644
--- a/docs/processing.md
+++ b/docs/processing.md
@@ -1,6 +1,6 @@
 # Processing data
 
-`qim3d` provides various tools for 3D image processing. Here, we provide a suite of powerful functionalities designed specifically for 3D image analysis and processing. From filter pipelines to structure tensor computation and blob detection, `qim3d` equips you with the tools you need to extract meaningful insights from your data.
+Here, we provide functionalities designed specifically for 3D image analysis and processing. From filter pipelines to structure tensor computation and blob detection, `qim3d` equips you with the tools you need to extract meaningful insights from your data.
 
 ::: qim3d.processing
     options:
@@ -9,4 +9,9 @@
             - local_thickness
             - get_3d_cc
             - Pipeline
-            - Blob
\ No newline at end of file
+            - Blob
+
+::: qim3d.processing.operations
+    options:
+        members:
+            - remove_background
diff --git a/docs/releases.md b/docs/releases.md
index 3f611b8c1992b6f31560b58bb54f1e59725a2bca..64a04fd7137771be248d71eddc0773b8cef93569 100644
--- a/docs/releases.md
+++ b/docs/releases.md
@@ -18,6 +18,7 @@ And remember to keep your pip installation [up to date](/qim3d/#upgrade) so that
 - Support for loading DICOM files with `qim3d.io.load`🎉
 - Introduction of `qim3d.processing.get_3d_cc` for 3D connected components and `qim3d.viz.plot_cc` for associated visualization 🎉
 - Introduction of `qim3d.viz.colormaps` for easy visualization of e.g. multi-label segmentation results 🎉
+- Introduction of `qim3d.processing.operations.background_removal` 🎉
 
 ### v0.3.2 (23/02/2024)
 
diff --git a/qim3d/processing/__init__.py b/qim3d/processing/__init__.py
index 18b959f02996a87d8e4a2c46c0577c02419ecae7..34dea0c4f0c556184277de549acf22dc9ad3f59e 100644
--- a/qim3d/processing/__init__.py
+++ b/qim3d/processing/__init__.py
@@ -2,4 +2,5 @@ from .local_thickness_ import local_thickness
 from .structure_tensor_ import structure_tensor
 from .filters import *
 from .detection import *
+from .operations import *
 from .cc import get_3d_cc
diff --git a/qim3d/processing/filters.py b/qim3d/processing/filters.py
index c7d39ef901f834aa12828c7f9cad014dd416b73a..354214c4d7e699de2c934cfbfed0710dd51e1c23 100644
--- a/qim3d/processing/filters.py
+++ b/qim3d/processing/filters.py
@@ -1,8 +1,12 @@
 """Provides filter functions and classes for image processing"""
 
-from typing import Union, Type
+from typing import Type, Union
+
 import numpy as np
 from scipy import ndimage
+from skimage import morphology
+
+from qim3d.io.logger import log
 
 __all__ = [
     "Gaussian",
@@ -10,10 +14,12 @@ __all__ = [
     "Maximum",
     "Minimum",
     "Pipeline",
+    "Tophat",
     "gaussian",
     "median",
     "maximum",
     "minimum",
+    "tophat",
 ]
 
 
@@ -85,6 +91,19 @@ class Minimum(FilterBase):
         """
         return minimum(input, **self.kwargs)
 
+class Tophat(FilterBase):
+    def __call__(self, input):
+        """
+        Applies a tophat filter to the input.
+
+        Args:
+            input: The input image or volume.
+
+        Returns:
+            The filtered image or volume.
+        """
+        return tophat(input, **self.kwargs)
+
 
 class Pipeline:
     """
@@ -243,3 +262,28 @@ def minimum(vol, **kwargs):
         The filtered image or volume.
     """
     return ndimage.minimum_filter(vol, **kwargs)
+
+def tophat(vol, **kwargs):
+    """
+    Remove background from the volume
+    Args:
+        vol: The volume to remove background from
+        radius: The radius of the structuring element (default: 3)
+        background: color of the background, 'dark' or 'bright' (default: 'dark'). If 'bright', volume will be inverted.
+    Returns:
+        vol: The volume with background removed
+    """
+    radius = kwargs["radius"] if "radius" in kwargs else 3
+    background = kwargs["background"] if "background" in kwargs else "dark"
+    
+    if background == "bright":
+            log.info("Bright background selected, volume will be temporarily inverted when applying white_tophat")
+            vol = np.invert(vol)
+    
+    selem = morphology.ball(radius)
+    vol = vol - morphology.white_tophat(vol, selem)
+
+    if background == "bright":
+        vol = np.invert(vol)
+    
+    return vol
diff --git a/qim3d/processing/operations.py b/qim3d/processing/operations.py
new file mode 100644
index 0000000000000000000000000000000000000000..70193564e4ccde690d61a71c70714ed3d1b4cbe9
--- /dev/null
+++ b/qim3d/processing/operations.py
@@ -0,0 +1,51 @@
+import numpy as np
+import qim3d.processing.filters as filters
+
+
+def remove_background(
+    vol: np.ndarray,
+    median_filter_size: int = 2,
+    min_object_radius: int = 3,
+    background: str = "dark",
+    **median_kwargs
+) -> np.ndarray:
+    """
+    Remove background from a volume using a qim3d filters.
+
+    Args:
+        vol (np.ndarray): The volume to remove background from.
+        median_filter_size (int, optional): The size of the median filter. Defaults to 2.
+        min_object_radius (int, optional): The radius of the structuring element for the tophat filter. Defaults to 3.
+        background (str, optional): The background type. Can be 'dark' or 'bright'. Defaults to 'dark'.
+        **median_kwargs: Additional keyword arguments for the Median filter.
+
+    Returns:
+        np.ndarray: The volume with background removed.
+
+
+    Example:
+        ```python
+        import qim3d
+
+        vol = qim3d.examples.cement_128x128x128
+        qim3d.viz.slices(vol, vmin=0, vmax=255)
+        ```
+        ![operations-remove_background_before](assets/screenshots/operations-remove_background_before.png)  
+
+        ```python
+        vol_filtered  = qim3d.processing.operations.remove_background(vol,
+                                                              min_object_radius=3, 
+                                                              background="bright")
+        qim3d.viz.slices(vol_filtered, vmin=0, vmax=255)
+        ```
+        ![operations-remove_background_after](assets/screenshots/operations-remove_background_after.png)
+    """
+
+    # Create a pipeline with a median filter and a tophat filter
+    pipeline = filters.Pipeline(
+        filters.Median(size=median_filter_size, **median_kwargs),
+        filters.Tophat(radius=min_object_radius, background=background),
+    )
+
+    # Apply the pipeline to the volume
+    return pipeline(vol)