Note
Go to the end to download the full example code.
14.9. Sample microscope
This script simulates a microscopic imaging system, generating a random noise image as a mock source and capturing it through a microscope with adjustable magnification, numerical aperture, and wavelength. It visualizes the original and processed images dynamically, demonstrating how changes in optical parameters affect image quality and resolution.
import astropy.units as u
import numpy as np
from openwfs.plot_utilities import grab_and_show, imshow
from openwfs.simulation import Microscope, StaticSource, Camera
specimen_resolution = (1024, 1024) # height × width in pixels of the specimen image
specimen_pixel_size = 60 * u.nm # resolution (pixel size) of the specimen image
magnification = 40 # magnification from object plane to camera.
numerical_aperture = 0.85 # numerical aperture of the microscope objective
wavelength = 532.8 * u.nm # wavelength of the light, for computing diffraction.
camera_resolution = (256, 256) # number of pixels on the camera
camera_pixel_size = 6.45 * u.um # Size of the pixels on the camera
p_limit = 100 # Number steps in the animation
# Create a random noise image with a few bright spots
src = StaticSource(
data=np.maximum(np.random.randint(-10000, 100, specimen_resolution, dtype=np.int16), 0),
pixel_size=specimen_pixel_size,
)
# Create a microscope with the given parameters
mic = Microscope(
src,
magnification=magnification,
numerical_aperture=numerical_aperture,
wavelength=wavelength,
)
# simulate shot noise in an 8-bit camera with auto-exposure:
cam = Camera(
mic,
analog_max=None,
shot_noise=True,
digital_max=255,
)
devices = {"camera": cam, "stage": mic.xy_stage}
if __name__ == "__main__":
import matplotlib.pyplot as plt
plt.subplot(1, 2, 1)
imshow(src.data)
plt.title("Original image")
plt.subplot(1, 2, 2)
plt.title("Scanned image")
ax = None
for p in range(p_limit):
mic.xy_stage.position = p * 1 * u.um
mic.z_stage.position = p * 0.1 * u.um # slowly drift out of focus
ax = grab_and_show(cam, ax)
plt.title(f"defocus: {mic.z_stage.position}")
plt.pause(0.2)