.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/basics/demo_spc.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_basics_demo_spc.py: Pattern Ordering in a Compressive Single Pixel Camera ======================================================== This demo illustrates the impact of different Hadamard pattern ordering algorithms in the Single Pixel Camera (SPC), a computational imaging system that uses a single photodetector to capture images by projecting the scene onto a series of patterns. The SPC is implemented in the DeepInverse library. In this example, we explore the following ordering algorithms for the Hadamard transform: 1. **Sequency Ordering**: Rows are ordered based on the number of sign changes (sequency pattern). Reference: https://en.wikipedia.org/wiki/Walsh_matrix#Sequency_ordering 2. **Cake Cutting Ordering**: Rows are ordered based on the number of blocks in the 2D resized Hadamard matrix. Reference: https://doi.org/10.3390/s19194122 3. **Zig-Zag Ordering**: Rows are ordered in a zig-zag pattern from the top-left to the bottom-right of the matrix. Reference: https://doi.org/10.1364/OE.451656 4. **XY Ordering**: Rows are ordered in a circular pattern starting from the top-left to the bottom-right. Reference: https://doi.org/10.48550/arXiv.2209.04449 We compare the reconstructions obtained using these orderings and visualize their corresponding masks and Hadamard spectrum. .. GENERATED FROM PYTHON SOURCE LINES 31-41 .. code-block:: Python import torch from pathlib import Path import matplotlib.pyplot as plt import deepinv as dinv from deepinv.utils.demo import get_image_url, load_url_image from deepinv.utils.plotting import plot from deepinv.loss.metric import PSNR from deepinv.physics.singlepixel import hadamard_2d_shift .. GENERATED FROM PYTHON SOURCE LINES 42-44 General Setup ------------- .. GENERATED FROM PYTHON SOURCE LINES 44-51 .. code-block:: Python BASE_DIR = Path(".") RESULTS_DIR = BASE_DIR / "results" # Set the global random seed for reproducibility. torch.manual_seed(0) device = dinv.utils.get_freer_gpu() if torch.cuda.is_available() else "cpu" .. GENERATED FROM PYTHON SOURCE LINES 52-55 Configuration ------------- Define the image size, noise level, number of measurements, and ordering algorithms. .. GENERATED FROM PYTHON SOURCE LINES 55-67 .. code-block:: Python img_size_H = 128 # Size of the image (128x128 pixels) img_size_W = 128 noise_level_img = 0.0 # Noise level in the image n = img_size_H * img_size_W # Total number of pixels in the image m = 5000 # Number of measurements orderings = [ "sequency", "cake_cutting", "zig_zag", "xy", ] # Ordering algorithms to compare .. GENERATED FROM PYTHON SOURCE LINES 68-71 Load Image ---------- Load a grayscale image from the internet and resize it to the desired size. .. GENERATED FROM PYTHON SOURCE LINES 71-80 .. code-block:: Python url = get_image_url("barbara.jpeg") x = load_url_image( url=url, img_size=(img_size_H, img_size_W), grayscale=True, resize_mode="resize", device=device, ) .. GENERATED FROM PYTHON SOURCE LINES 81-84 Create Physics Models --------------------- Instantiate Single Pixel Camera models with different ordering algorithms. .. GENERATED FROM PYTHON SOURCE LINES 84-95 .. code-block:: Python physics_list = [ dinv.physics.SinglePixelCamera( m=m, img_shape=(1, img_size_H, img_size_W), noise_model=dinv.physics.GaussianNoise(sigma=noise_level_img), device=device, ordering=ordering, ) for ordering in orderings ] .. GENERATED FROM PYTHON SOURCE LINES 96-99 Generate Measurements and Reconstructions ----------------------------------------- Generate measurements using the physics models and reconstruct images using the adjoint operator. .. GENERATED FROM PYTHON SOURCE LINES 99-102 .. code-block:: Python y_list = [physics(x) for physics in physics_list] x_list = [physics.A_adjoint(y) for physics, y in zip(physics_list, y_list)] .. GENERATED FROM PYTHON SOURCE LINES 103-106 Calculate PSNR -------------- Compute the Peak Signal-to-Noise Ratio (PSNR) for each reconstruction. .. GENERATED FROM PYTHON SOURCE LINES 106-123 .. code-block:: Python psnr_metric = PSNR() psnr_values = [psnr_metric(x_recon, x).item() for x_recon in x_list] # Prepare titles for plotting title_orderings = [o.replace("_", " ").title() for o in orderings] title_orderings[-1] = "XY" # Special case for 'xy' titles = ["Ground Truth"] + [ f"{ordering}\nPSNR: {psnr:.2f}" for ordering, psnr in zip(title_orderings, psnr_values) ] # Print information about the SPC setup undersampling_rate = physics_list[0].mask.sum().float() / n print(f"Image Size: {x.shape}") print(f"SPC Measurements: {physics_list[0].mask.sum()}") print(f"SPC Undersampling Rate: {undersampling_rate:.2f}") .. rst-class:: sphx-glr-script-out .. code-block:: none Image Size: torch.Size([1, 1, 128, 128]) SPC Measurements: 5000.0 SPC Undersampling Rate: 0.31 .. GENERATED FROM PYTHON SOURCE LINES 124-127 Plot Reconstructions -------------------- Visualize the ground truth and reconstructed images with PSNR values. .. GENERATED FROM PYTHON SOURCE LINES 127-187 .. code-block:: Python plot([x] + x_list, titles=titles, show=True, figsize=(15, 5)) # Recovery Algorithm # ------------------ # Use a Plug-and-Play (PnP) denoising prior with the ADMM optimization algorithm for image recovery. from deepinv.models import DnCNN from deepinv.optim.data_fidelity import L2 from deepinv.optim.prior import PnP from deepinv.optim.optimizers import optim_builder n_channels = 1 # Number of channels in the image # Define the data fidelity term (L2 loss) data_fidelity = L2() # Specify the denoising prior using a pretrained DnCNN model denoiser = DnCNN( in_channels=n_channels, out_channels=n_channels, pretrained="download", # Automatically downloads pretrained weights device=device, ) # Define the prior using the Plug-and-Play framework prior = PnP(denoiser=denoiser) # Set optimization parameters max_iter = 5 # Maximum number of iterations noise_level_img = 0.03 # Noise level in the image params_algo = {"stepsize": 0.8, "g_param": noise_level_img} # Instantiate the optimization algorithm (ADMM) model = optim_builder( iteration="ADMM", prior=prior, data_fidelity=data_fidelity, early_stop=False, max_iter=max_iter, verbose=False, params_algo=params_algo, g_first=True, ) # Set the model to evaluation mode (no training required) model.eval() # Perform image reconstruction using the optimization algorithm x_recon = [] psnr_values = [] for y, physics in zip(y_list, physics_list): x_recon.append(model(y, physics)) psnr_values.append(psnr_metric(x_recon[-1], x).item()) # Update titles with PSNR values for the reconstructed images titles = ["Ground Truth"] + [ f"{ordering}\nPSNR: {psnr:.2f}" for ordering, psnr in zip(title_orderings, psnr_values) ] .. image-sg:: /auto_examples/basics/images/sphx_glr_demo_spc_001.png :alt: Ground Truth, Sequency PSNR: 27.33, Cake Cutting PSNR: 29.88, Zig Zag PSNR: 29.10, XY PSNR: 29.40 :srcset: /auto_examples/basics/images/sphx_glr_demo_spc_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none Downloading: "https://huggingface.co/deepinv/dncnn/resolve/main/dncnn_sigma2_gray.pth?download=true" to /home/runner/.cache/torch/hub/checkpoints/dncnn_sigma2_gray.pth 0%| | 0.00/2.55M [00:00` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: demo_spc.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: demo_spc.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_