Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ML4Science 2023: Phase masks implementations #110

Open
wants to merge 132 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
132 commits
Select commit Hold shift + click to select a range
72d0f58
add psf.tiff file
aelalamy42 Nov 17, 2023
96e91b4
Merge branch 'LCAV:main' into main
aelalamy42 Nov 18, 2023
f639321
Merge branch 'main' of github.com:aelalamy42/LenslessPiCam_ML4Science…
aelalamy42 Nov 20, 2023
e68531c
First test for using torch
Ghita2002 Nov 21, 2023
521bba1
Merge branch 'main' of https://github.com/aelalamy42/LenslessPiCam_ML…
Ghita2002 Nov 21, 2023
e0d76bd
Merge branch 'main' of https://github.com/aelalamy42/LenslessPiCam_ML…
Nov 21, 2023
c2646a5
create_mask into torch
Ghita2002 Nov 21, 2023
331e327
phase_retrieval in torch
aelalamy42 Nov 21, 2023
c229522
Merge branch 'Work_Ghita' of https://github.com/aelalamy42/LenslessPi…
Ghita2002 Nov 21, 2023
5e12425
added the height varying mask
Seif-Wessam Nov 23, 2023
356d6ba
MultiLensArray initialization
Ghita2002 Nov 25, 2023
388daf1
Merge branch 'Work_Ghita' of https://github.com/aelalamy42/LenslessPi…
Ghita2002 Nov 25, 2023
515fd11
Adding comments to mask.py
Ghita2002 Nov 25, 2023
0f2d9d1
first half of the MLA
aelalamy42 Nov 25, 2023
eeb9399
implement overlapping check
aelalamy42 Nov 25, 2023
9ce0426
Multilens kind of done and tested
aelalamy42 Nov 26, 2023
b8151a9
Merge pull request #1 from aelalamy42/Work_Ahmed
aelalamy42 Nov 27, 2023
12c63f2
height varying tested
aelalamy42 Nov 27, 2023
7b2a1a4
Update mask.py
aelalamy42 Nov 27, 2023
1dc82fc
Multilens patched
aelalamy42 Nov 27, 2023
2d4d5fc
Merge pull request #2 from aelalamy42/aelalamy42-patch-1
aelalamy42 Nov 27, 2023
7b85737
Merge branch 'main' into travail_seif
aelalamy42 Nov 27, 2023
160c802
Merge pull request #3 from aelalamy42/travail_seif
aelalamy42 Nov 27, 2023
0951bd9
added the torch implementation (as a 2nd option) to the HeightVarying…
Seif-Wessam Nov 27, 2023
228ca0d
set is_torch to TRUE for the height_varying mask
Seif-Wessam Nov 28, 2023
af1818c
added the test for the torch case in test_masks.py
Seif-Wessam Nov 28, 2023
d882653
Merge branch 'main' into Work_Ghita
Ghita2002 Nov 29, 2023
2bd322c
from numpy to torch
Ghita2002 Nov 29, 2023
51e6966
edits to the pytorch implementation
Seif-Wessam Nov 30, 2023
9254864
added the device to HeightVarying
Seif-Wessam Nov 30, 2023
2a92bbb
added the device
Seif-Wessam Nov 30, 2023
7209fee
fix phase of multilens
aelalamy42 Nov 30, 2023
613dc07
added is_Torch to the constructor and to compute_psf
Seif-Wessam Nov 30, 2023
af26708
changed the compute_psf function to include is_torch
Seif-Wessam Nov 30, 2023
def924c
some tests
Ghita2002 Nov 30, 2023
d2684bc
fixed the heightVarying with torch
Seif-Wessam Nov 30, 2023
26acdd1
changed the testing code to have is_Torch=True
Seif-Wessam Nov 30, 2023
de51f5c
corrected the code for testing the torch part of HeightVaryingMask
Seif-Wessam Dec 1, 2023
8c4b49b
improvement to the test.
Seif-Wessam Dec 2, 2023
2cfaa7f
fix phase of multilens
aelalamy42 Dec 4, 2023
fffdc77
merge main
aelalamy42 Dec 4, 2023
394201b
torch implementation of height varying
aelalamy42 Dec 4, 2023
b5aa4c0
Merge pull request #4 from aelalamy42/travail_seif
aelalamy42 Dec 4, 2023
e0dfb26
merge main
aelalamy42 Dec 4, 2023
0796d58
merge main
aelalamy42 Dec 4, 2023
e174292
merge main
aelalamy42 Dec 4, 2023
9282404
not working for now
aelalamy42 Dec 4, 2023
6ee4be4
add comments
aelalamy42 Dec 4, 2023
3780cd1
finish the torch implementation of MLA
aelalamy42 Dec 5, 2023
5717b7c
Merge branch 'main' of github.com:aelalamy42/LenslessPiCam_ML4Science…
aelalamy42 Dec 5, 2023
f2c3c29
Start interface for trainable coded aperture.
ebezzam Dec 6, 2023
cd76a3c
Update trainable mask interface.
ebezzam Dec 6, 2023
21f0d08
beginning of multilens in trainable
aelalamy42 Dec 6, 2023
bc15721
Merge pull request #5 from aelalamy42/Work_Ghita
aelalamy42 Dec 6, 2023
73bb229
Improve trainable mask API.
ebezzam Dec 6, 2023
5e1f8cc
Fix MURA.
ebezzam Dec 6, 2023
2ceca9d
merge main
aelalamy42 Dec 7, 2023
ee71705
Merge branch 'main' of github.com:aelalamy42/LenslessPiCam_ML4Science…
aelalamy42 Dec 7, 2023
922c866
matching names
aelalamy42 Dec 7, 2023
6ae7f21
Merge pull request #7 from aelalamy42/LCAV-trainable_amplitude_mask
aelalamy42 Dec 7, 2023
177a6e9
beginning of trainable multilensArray
aelalamy42 Dec 7, 2023
218ade8
project fonction, TrainableMultiLensArray constru
Ghita2002 Dec 7, 2023
a7847b8
update project
aelalamy42 Dec 7, 2023
ab3f233
Merge pull request #8 from aelalamy42/Work_Ghita
aelalamy42 Dec 7, 2023
3ed5fee
added TrainableHeightVarying in lensless/hardware/trainable_mask.py
Seif-Wessam Dec 7, 2023
6b66d4f
Merge branch 'main' of github.com:aelalamy42/LenslessPiCam_ML4Science…
aelalamy42 Dec 10, 2023
89e73de
train_multilens_array.yaml
aelalamy42 Dec 10, 2023
72636a9
Merge branch 'main' of github.com:aelalamy42/LenslessPiCam_ML4Science…
aelalamy42 Dec 10, 2023
54e0ab2
cleaner code
aelalamy42 Dec 10, 2023
37b4b11
Merge pull request #9 from aelalamy42/Work_Ghita
aelalamy42 Dec 10, 2023
b13a6f6
minor typo
aelalamy42 Dec 10, 2023
5292ea8
minor change in TrainableHeightVarying
Seif-Wessam Dec 10, 2023
85518e5
minor typo
aelalamy42 Dec 10, 2023
8adea38
changes to TrainableHeightVarying
Seif-Wessam Dec 10, 2023
100777c
update mask too
aelalamy42 Dec 10, 2023
f0b631a
debug
aelalamy42 Dec 10, 2023
b73f406
debug
aelalamy42 Dec 10, 2023
ffa42fd
debug
aelalamy42 Dec 10, 2023
1eb99d8
debug
aelalamy42 Dec 10, 2023
aa3d71d
change to TrainableHeightVaryingMask
Seif-Wessam Dec 10, 2023
f5df5a7
limit number of files
aelalamy42 Dec 10, 2023
529e3ad
typo fix
Seif-Wessam Dec 11, 2023
4d78a55
little changes
aelalamy42 Dec 11, 2023
26bc878
Merge branch 'main' of github.com:aelalamy42/LenslessPiCam_ML4Science…
aelalamy42 Dec 11, 2023
177de56
changesé
aelalamy42 Dec 11, 2023
52eab65
Merge pull request #10 from aelalamy42/travail_seif
aelalamy42 Dec 11, 2023
603ce44
add yaml file for height varying
aelalamy42 Dec 11, 2023
61651cf
Fix coded aperture training (fashion mnist).
ebezzam Dec 13, 2023
db6244d
few changes
aelalamy42 Dec 14, 2023
4444859
Merge pull request #11 from LCAV/trainable_amplitude_mask
aelalamy42 Dec 14, 2023
a374156
Set coded aperture optimization to grayscale.
ebezzam Dec 15, 2023
3d7c3b8
Merge pull request #12 from LCAV/trainable_amplitude_mask
aelalamy42 Dec 15, 2023
3751448
minor changes
aelalamy42 Dec 15, 2023
6205c5c
merge main
aelalamy42 Dec 15, 2023
359218d
push new changes
aelalamy42 Dec 15, 2023
ce8c504
torch.no_grad and other changes
aelalamy42 Dec 15, 2023
21323dd
new optimization of multilens heightmap computation
aelalamy42 Dec 16, 2023
54535c9
trying on google colab
aelalamy42 Dec 16, 2023
f475fa2
trying on google colab
aelalamy42 Dec 16, 2023
ebf159c
commit back
aelalamy42 Dec 16, 2023
fc18147
check that on GPU it works
aelalamy42 Dec 18, 2023
6fb1ef3
small changes
aelalamy42 Dec 18, 2023
e850991
small debug
aelalamy42 Dec 18, 2023
1932e35
small debug
aelalamy42 Dec 18, 2023
29f0126
Correctly set torch device.
ebezzam Dec 18, 2023
d2cc322
Move prep trainable mask into package.
ebezzam Dec 18, 2023
321154f
Set wavelength and optimizer param through config.
ebezzam Dec 18, 2023
28356c3
Merge branch 'trainable_amplitude_mask' of github.com:LCAV/LenslessPi…
aelalamy42 Dec 18, 2023
73befd0
Merge
aelalamy42 Dec 18, 2023
10c2179
changes
aelalamy42 Dec 18, 2023
951c1ae
changes
aelalamy42 Dec 18, 2023
8bb09f4
changes
aelalamy42 Dec 18, 2023
cf6be5c
changes
aelalamy42 Dec 18, 2023
5896496
changes
aelalamy42 Dec 18, 2023
953bcdc
changes
aelalamy42 Dec 18, 2023
807dff3
changes
aelalamy42 Dec 18, 2023
99b00d0
changes
aelalamy42 Dec 18, 2023
9be48e7
changes
aelalamy42 Dec 18, 2023
dd3cc2c
changes
aelalamy42 Dec 18, 2023
a5607eb
changes
aelalamy42 Dec 18, 2023
f256f5c
changes
aelalamy42 Dec 18, 2023
b0a3f64
changes
aelalamy42 Dec 18, 2023
ba8975c
changes
aelalamy42 Dec 18, 2023
db5e7a9
changes
aelalamy42 Dec 18, 2023
20fefa2
changes
aelalamy42 Dec 18, 2023
d155b70
changes
aelalamy42 Dec 18, 2023
f4f13d6
changes
aelalamy42 Dec 18, 2023
8c35575
changes
aelalamy42 Dec 18, 2023
9bdf313
changes
aelalamy42 Dec 18, 2023
c242ebd
debugging session
aelalamy42 Dec 19, 2023
b28802e
Update README.rst
aelalamy42 Dec 20, 2023
63485c0
Merge pull request #14 from aelalamy42/aelalamy42-patch-2
aelalamy42 Dec 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 6 additions & 149 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,70 +1,20 @@
=============
LenslessPiCam
=============
Ahmed Elalamy (324610), Seif Hamed (312081), Ghita Tagemouati (330383)

.. image:: https://readthedocs.org/projects/lensless/badge/?version=latest
:target: http://lensless.readthedocs.io/en/latest/
:alt: Documentation Status


.. image:: https://joss.theoj.org/papers/10.21105/joss.04747/status.svg
:target: https://doi.org/10.21105/joss.04747
:alt: DOI

.. image:: https://static.pepy.tech/badge/lensless
:target: https://www.pepy.tech/projects/lensless
:alt: Downloads


*A Hardware and Software Toolkit for Lensless Computational Imaging with a Raspberry Pi*
-----------------------------------------------------------------------------------------

.. image:: https://github.com/LCAV/LenslessPiCam/raw/main/scripts/recon/example.png
:alt: Lensless imaging example
:align: center


This toolkit has everything you need to perform imaging with a lensless
camera. We make use of a low-cost implementation of DiffuserCam [1]_,
where we use a piece of tape instead of the lens and the
`Raspberry Pi HQ camera sensor <https://www.raspberrypi.com/products/raspberry-pi-high-quality-camera>`__
(the `V2 sensor <https://www.raspberrypi.com/products/camera-module-v2/>`__
is also supported). Similar principles and methods can be used for a
different lensless encoder and a different sensor.

*If you are interested in exploring reconstruction algorithms without building the camera, that is entirely possible!*
The provided reconstruction algorithms can be used with the provided data or simulated data.

We've also written a few Medium articles to guide users through the process
of building the camera, measuring data with it, and reconstruction.
They are all laid out in `this post <https://medium.com/@bezzam/a-complete-lensless-imaging-tutorial-hardware-software-and-algorithms-8873fa81a660>`__.
Our work is mainly done in the trainable_mask.py and mask.py files.

Setup
-----

If you are just interested in using the reconstruction algorithms and
plotting / evaluation tools you can install the package via ``pip``:
First, install the lensless package

.. code:: bash

pip install lensless


For plotting, you may also need to install
`Tk <https://stackoverflow.com/questions/5459444/tkinter-python-may-not-be-configured-for-tk>`__.


For performing measurements, the expected workflow is to have a local
computer which interfaces remotely with a Raspberry Pi equipped with
the HQ camera sensor (or V2 sensor). Instructions on building the camera
can be found `here <https://lensless.readthedocs.io/en/latest/building.html>`__.

The software from this repository has to be installed on **both** your
local machine and the Raspberry Pi. Note that we highly recommend using
Python 3.9, as some Python library versions may not be available with
earlier versions of Python. Moreover, its `end-of-life <https://endoflife.date/python>`__
is Oct 2025.

*Local machine setup*
=====================

Expand Down Expand Up @@ -92,101 +42,8 @@ install the library locally.

# extra dependencies for local machine for plotting/reconstruction
pip install -r recon_requirements.txt
pip install -r mask_requirements.txt

# (optional) try reconstruction on local machine
python scripts/recon/admm.py

# (optional) try reconstruction on local machine with GPU
python scripts/recon/admm.py -cn pytorch


Note (25-04-2023): for using the :py:class:`~lensless.recon.apgd.APGD` reconstruction method based on Pycsou
(now `Pyxu <https://github.com/matthieumeo/pyxu>`__), a specific commit has
to be installed (as there was no release at the time of implementation):

.. code:: bash

pip install git+https://github.com/matthieumeo/pycsou.git@38e9929c29509d350a7ff12c514e2880fdc99d6e

If PyTorch is installed, you will need to be sure to have PyTorch 2.0 or higher,
as Pycsou is not compatible with earlier versions of PyTorch. Moreover,
Pycsou requires Python within
`[3.9, 3.11) <https://github.com/matthieumeo/pycsou/blob/v2-dev/setup.cfg#L28>`__.

Moreover, ``numba`` (requirement for Pycsou V2) may require an older version of NumPy:

.. code:: bash

pip install numpy==1.23.5

*Raspberry Pi setup*
====================

After `flashing your Raspberry Pi with SSH enabled <https://medium.com/@bezzam/setting-up-a-raspberry-pi-without-a-monitor-headless-9a3c2337f329>`__,
you need to set it up for `passwordless access <https://medium.com/@bezzam/headless-and-passwordless-interfacing-with-a-raspberry-pi-ssh-453dd75154c3>`__.
Do not set a password for your SSH key pair, as this will not work with the
provided scripts.

On the Raspberry Pi, you can then run the following commands (from the ``home``
directory):

.. code:: bash

# dependencies
sudo apt-get install -y libimage-exiftool-perl libatlas-base-dev \
python3-numpy python3-scipy python3-opencv
sudo pip3 install -U virtualenv

# download from GitHub
git clone [email protected]:LCAV/LenslessPiCam.git

# install in virtual environment
cd LenslessPiCam
virtualenv --system-site-packages -p python3 lensless_env
source lensless_env/bin/activate
pip install --no-deps -e .
pip install -r rpi_requirements.txt


Acknowledgements
----------------

The idea of building a lensless camera from a Raspberry Pi and a piece of
tape comes from Prof. Laura Waller's group at UC Berkeley. So a huge kudos
to them for the idea and making tools/code/data available! Below is some of
the work that has inspired this toolkit:

* `Build your own DiffuserCam tutorial <https://waller-lab.github.io/DiffuserCam/tutorial>`__.
* `DiffuserCam Lensless MIR Flickr dataset <https://waller-lab.github.io/LenslessLearning/dataset.html>`__ [2]_.

A few students at EPFL have also contributed to this project:

* Julien Sahli: support and extension of algorithms for 3D.
* Yohann Perron: unrolled algorithms for reconstruction.

Citing this work
----------------

If you use these tools in your own research, please cite the following:

::

@article{Bezzam2023,
doi = {10.21105/joss.04747},
url = {https://doi.org/10.21105/joss.04747},
year = {2023},
publisher = {The Open Journal},
volume = {8},
number = {86},
pages = {4747},
author = {Eric Bezzam and Sepand Kashani and Martin Vetterli and Matthieu Simeoni},
title = {LenslessPiCam: A Hardware and Software Platform for Lensless Computational Imaging with a Raspberry Pi},
journal = {Journal of Open Source Software}
}

References
----------

.. [1] Antipa, N., Kuo, G., Heckel, R., Mildenhall, B., Bostan, E., Ng, R., & Waller, L. (2018). DiffuserCam: lensless single-exposure 3D imaging. Optica, 5(1), 1-9.
# training with the height varying mask
python scripts/recon/train_unrolled.py -cn train_heightvarying

.. [2] Monakhova, K., Yurtsever, J., Kuo, G., Antipa, N., Yanny, K., & Waller, L. (2019). Learned reconstructions for practical mask-based lensless imaging. Optics express, 27(20), 28075-28090.
55 changes: 55 additions & 0 deletions configs/train_coded_aperture.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# python scripts/recon/train_unrolled.py -cn train_coded_aperture
defaults:
- train_unrolledADMM
- _self_

# Train Dataset
files:
dataset: mnist # Simulated : "mnist", "fashion_mnist", "cifar10", "CelebA". Measure :"DiffuserCam"
celeba_root: /scratch/bezzam
downsample: 16 # TODO use downsample simulation instead?
n_files: 100
crop:
vertical: [810, 2240]
horizontal: [1310, 2750]

torch_device: "cuda"

optimizer:
# type: Adam # Adam, SGD...
# lr: 1e-4
type: SGD
lr: 0.01

#Trainable Mask
trainable_mask:
mask_type: TrainableCodedAperture
# optimizer: Adam
# mask_lr: 1e-3
optimizer: SGD
mask_lr: 0.01
L1_strength: False
binary: False
initial_value:
psf_wavelength: [550e-9]
method: MLS
n_bits: 8 # (2**n_bits-1, 2**n_bits-1)
# method: MURA
# n_bits: 25 # (4*nbits*1, 4*nbits*1)
# # -- applicable for phase masks
# design_wv: 550e-9

simulation:
grayscale: True
flip: False
scene2mask: 40e-2
mask2sensor: 2e-3
sensor: "rpi_hq"
object_height: 0.30

training:
crop_preloss: True # crop region for computing loss
batch_size: 4
epoch: 25
eval_batch_size: 16
save_every: 1
43 changes: 43 additions & 0 deletions configs/train_heightvarying.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# python scripts/recon/train_unrolled.py -cn train_multilens_array
defaults:
- train_unrolledADMM
- _self_

# Train Dataset
files:
dataset: fashion_mnist # Simulated : "mnist", "fashion_mnist", "cifar10", "CelebA". Measure :"DiffuserCam"
celeba_root: /scratch/bezzam
downsample: 16 # TODO use simulation instead?
n_files: 100
crop:
vertical: [810, 2240]
horizontal: [1310, 2750]

torch_device: "cuda:0"

#Trainable Mask
trainable_mask:
mask_type: TrainableHeightVarying
optimizer: Adam
mask_lr: 1e-3
L1_strength: False
binary: False
initial_value:
psf_wavelength: [550e-9]
design_wv: 550e-9

simulation:
grayscale: True
flip: False
scene2mask: 40e-2
mask2sensor: 2e-3
sensor: "rpi_hq"
downsample: 16
object_height: 0.30

training:
crop_preloss: True # crop region for computing loss
batch_size: 2
epoch: 25
eval_batch_size: 16
save_every: 1
44 changes: 44 additions & 0 deletions configs/train_multilens_array.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# python scripts/recon/train_unrolled.py -cn train_multilens_array
defaults:
- train_unrolledADMM
- _self_

# Train Dataset
files:
dataset: fashion_mnist # Simulated : "mnist", "fashion_mnist", "cifar10", "CelebA". Measure :"DiffuserCam"
celeba_root: /scratch/bezzam
downsample: 16 # TODO use simulation instead?
n_files: 100
crop:
vertical: [810, 2240]
horizontal: [1310, 2750]

torch_device: "cpu"

#Trainable Mask
trainable_mask:
mask_type: TrainableMultiLensArray
optimizer: Adam
mask_lr: 1e-3
L1_strength: False
binary: False
initial_value:
N : 10 #TODO: check this value ?
psf_wavelength: [550e-9]
design_wv: 550e-9

simulation:
grayscale: True
flip: False
scene2mask: 40e-2
mask2sensor: 2e-3
sensor: "rpi_hq"
downsample: 16
object_height: 0.30

training:
crop_preloss: True # crop region for computing loss
batch_size: 2
epoch: 25
eval_batch_size: 16
save_every: 1
3 changes: 2 additions & 1 deletion configs/train_unrolledADMM.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ trainable_mask:
initial_value: psf
grayscale: False
mask_lr: 1e-3
optimizer: Adam # Adam, SGD... (Pytorch class)
L1_strength: 1.0 #False or float

target: "object_plane" # "original" or "object_plane" or "label"
Expand Down Expand Up @@ -129,7 +130,7 @@ training:
crop_preloss: True # crop region for computing loss

optimizer:
type: Adam
type: Adam # Adam, SGD... (Pytorch class)
lr: 1e-4
slow_start: False #float how much to reduce lr for first epoch
# Decay LR in step fashion: https://pytorch.org/docs/stable/generated/torch.optim.lr_scheduler.StepLR.html
Expand Down
Binary file added data/psf.tiff
Binary file not shown.
4 changes: 2 additions & 2 deletions lensless/eval/benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ def benchmark(

for i, idx in enumerate(batch_idx):
if idx in save_idx:
prediction_np = prediction.cpu().numpy()[i].squeeze()
# switch to [H, W, C]
prediction_np = prediction.cpu().numpy()[i]
# switch to [H, W, C] for saving
prediction_np = np.moveaxis(prediction_np, 0, -1)
save_image(prediction_np, fp=os.path.join(output_dir, f"{idx}.png"))

Expand Down
Loading
Loading