A smoothing Gaussian filter is a weighted blur: each voxel becomes a neighbour-average with bell-curve weights (closest counts most). It is a denoise step. It is not “what is preprocessing.” It is not resampling. It is not a PYCAD filter product.
If you meant the whole preprocess menu → what is image preprocessing (6249 already names Gaussian as one denoise line). If you meant change spacing → resampling. If you meant intensity scale → image normalization. If you meant tabular rows → data preprocessing for machine learning. If you meant crop, same grid → medical imaging cropping. If you meant RandGaussianNoised as aug → MONAI 3D augmentation.
680’s keepers do not own this URL. 6249 mentions the filter in passing; 6192 uses “Gaussian” as a data shape, not a kernel. This page is the kernel. PYCAD builds custom web DICOM viewers and imaging models. It does not ship a smoother.
What the kernel is doing
| Knob | Meaning | What you trade |
|---|---|---|
| Sigma (σ) | Width of the bell, in pixels (or millimetres if the filter honours spacing) | Larger σ → more blur, more SNR, softer edges |
| Kernel size | The window you actually convolve. OpenCV wants an odd ksize |
Too small vs σ and you truncate the bell. Too big and you pay compute for near-zero weights |
| Box / mean filter | Same window, equal weights | Cheaper. Blockier. Worse at keeping an edge |
| Median | Neighbourhood median, not a mean | Salt-and-pepper. Not this page |
A Gaussian is a low-pass. Fine grain goes. So does a 1-voxel vessel if σ is fat. On a CT, that is how a small nodule becomes a smudge and a “cleaner” screenshot. Do not smooth, then measure volume, then call the change biology.
Separable: a 3D Gaussian is three 1D passes. That is why SciPy and SimpleITK stay cheap on a volume. Anisotropic spacing (0.7 mm in-plane, 2.5 mm slices) means a σ of “2 voxels” is not the same millimetres on z. Prefer a filter that can take physical units, or scale σ per axis.
OpenCV (a 2D slice)
Good for a PNG or a single extracted slice. ksize must be odd and positive. sigmaX=0 means OpenCV picks σ from the kernel — fine for a demo, lazy for a protocol. Set both.
import cv2
img = cv2.imread("slice.png", cv2.IMREAD_GRAYSCALE)
if img is None:
raise SystemExit("missing slice.png")
blur = cv2.GaussianBlur(img, ksize=(5, 5), sigmaX=1.0, sigmaY=1.0)
cv2.imwrite("slice_gauss.png", blur)
SciPy (a numpy volume)
σ is the knob. A tuple is per-axis, in array index order — numpy medical volumes are usually (z, y, x):
import numpy as np
from scipy.ndimage import gaussian_filter
vol = np.load("volume.npy") # (z, y, x)
# less blur along z if slices are already thick
smooth = gaussian_filter(vol, sigma=(0.5, 1.0, 1.0))
np.save("volume_gauss.npy", smooth)
This does not touch origin, spacing, or direction. If you write it back as NIfTI, copy those from the parent or you have a pretty array in the wrong patient.
SimpleITK (keep the tags)
DiscreteGaussian takes variance (σ²), not σ. SetUseImageSpacing(True) is how you speak millimetres instead of voxels:
import SimpleITK as sitk
img = sitk.ReadImage("ct.nii.gz")
g = sitk.DiscreteGaussianImageFilter()
g.SetVariance(1.0) # σ² in mm² when spacing is on
g.SetUseImageSpacing(True)
out = g.Execute(img)
sitk.WriteImage(out, "ct_gauss.nii.gz")
SmoothingRecursiveGaussian is the other SimpleITK name; it takes σ directly. Same idea. A mask is not a CT: do not Gaussian a labelmap unless you meant to turn 0/1 into 0.4. That is how a Dice score lies.
What this page is not
- Not 6249, 3351, 6175, 6192, or 378 restated with a “Gaussian” costume. Those are the 680 keepers and the crop how-to.
- Not MONAI
RandGaussianNoised. That is noise added for aug, the opposite direction. - Not finance charts, CMB maps, or an AI-denoiser affiliate. Dropped.
- Not a PYCAD filter SKU.
/portfoliois not the case-studies URL.
Install is pip install opencv-python scipy SimpleITK — pick the one that matches the file you have. If the smooth has to run inside a clinic viewer, that is the imaging piece. Case studies.