In [1]:
import imageio
import imageio.v3 as iio
from PIL import Image
import numpy as np
import matplotlib as plt
import sys
import matplotlib as plt
from numba import njit
# ==============================================================================

def create_png_from_M(
        M,
        fname="image.jpg",
    ):
    logger.info("create_png_from_M")
    plt.image.imsave(fname, M)


def get_M_from_png(
        fname,
    ):
    logger.info("def get_M_from_png(")
    img =  iio.imread(fname)
    return  np.array(img)
    

def get_M_from_jpg(
        fname,
    ):
    logger.info("get_M_from_jpg")
    img = imageio.imread(fname)
    return  np.array(img)


@njit
def create_Maustereo_njit(
        Mdepthmap, 
        Mwallpaper,
        d_factor, 
        symmetry,
    ):
    # ---------------------------------------------------------------
    imax_depthmap, jmax_depthmap  = Mdepthmap.shape                          # height of Mdepthmap, width  of Mdepthmap
    imax_wallpaper, jmax_wallpaper = Mwallpaper.shape[:2]                    # height of Mwallpaper, width  of Mwallpaper
    # ---------------------------------------------------------------
    V = np.zeros(jmax_depthmap + jmax_wallpaper)
    jmax_austere = jmax_depthmap + int(jmax_wallpaper * (1-d_factor))           # jmax_austere is a little bit larger than jmax_depthmap:
    # ---------------------------------------------------------------
    Maustereo = np.zeros((imax_depthmap, jmax_austere, 3), dtype=np.uint8)
    for i1 in range(imax_depthmap):                                        # loop over all lines in Mdepthmap                               
        for j in range(jmax_wallpaper):
            V[j] = j
        d_old = jmax_wallpaper
        for j1 in range(jmax_depthmap): # loop over all columns in current line
            d = int((1. - d_factor * Mdepthmap[i1,j1]) * jmax_wallpaper)
            V[j1 + d] = V[j1]
            if (d > d_old): # regenerate dismembered Mwallpaper?
                for k in range(d-d_old):
                    V[j1 + d - k - 1] = (V[j1 ] + jmax_wallpaper - k - 1) % jmax_wallpaper
            d_old = d
        for j1 in range(jmax_austere):
            n = V[j1] - V[int(symmetry * jmax_austere)] + jmax_wallpaper
            idx_shifted = int(n % jmax_wallpaper)
            i2 = i1 % imax_wallpaper
            Maustereo[i1,j1,:] = Mwallpaper[i2, idx_shifted,:]
    return Maustereo



def create_Maustereo_from_2M(
        Mdepthmap, 
        Mwallpaper,
        d_factor=0.25, 
        symmetry=0.5,
    ):
    logger.info("create_Maustereo")
    logger.info(f"\t {len(Mdepthmap.shape)=}")
    # ---------------------------------------------------------------
    if (len(Mdepthmap.shape)>2):
        logger.warning('Mdepthmap is probably not a greyscale image')
        return
    # ---------------------------------------------------------------
    if (Mwallpaper.shape[2]==4):
        # remove transparency layer:
        Mwallpaper = Mwallpaper[:,:,:3]
    # ---------------------------------------------------------------
    Maustereo = create_Maustereo_njit(
                                        Mdepthmap, 
                                        Mwallpaper,
                                        d_factor, 
                                        symmetry,
                                    )
    return Maustereo
In [9]:
ls
autostereo.ipynb  depthmap/  Depthmaps/  Motifs/  wallpaper/

Chargment de la matrice du motif 3D¶

In [21]:
# Pour les fichiers jpg
Mdepth = get_M_from_jpg("depthmap/Boule perforée et aiguille 1600.JPG")[:,:,0]/256
  INFO | 2026-01-14 06:29 |      image |    34 |   get_M_from_jpg
In [18]:
# Pour les fichiers png
Mdepth = get_M_from_jpg("depthmap/TTB Ripple F 4000x3000.png")/256
  INFO | 2026-01-14 06:29 |      image |    34 |   get_M_from_jpg

Chargment de la matrice du motif papier-peint¶

In [11]:
Mwall = get_M_from_jpg("wallpaper/Motif graphene rouge et gris.jpg")
  INFO | 2026-01-14 06:21 |      image |    33 |   get_M_from_jpg

Création de la matrice de l'autostéréogramme¶

In [19]:
%%time
Mas = create_Maustereo_from_2M(Mdepth, Mwall)
  INFO | 2026-01-14 06:29 | autostereo |    52 |   create_Maustereo
  INFO | 2026-01-14 06:29 | autostereo |    53 |   	 len(Mdepthmap.shape)=2
CPU times: user 183 ms, sys: 18.8 ms, total: 201 ms
Wall time: 201 ms

Création de l'image de l'autostéréogramme¶

In [20]:
%%time
create_png_from_M(Mas, "as2.png")
  INFO | 2026-01-14 06:29 |      image |    19 |   create_png_from_M
CPU times: user 714 ms, sys: 0 ns, total: 714 ms
Wall time: 713 ms