import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
def make_checkerboard(horizontal_pattern=20, vertical_pattern=20, repetitions=(10, 10)):
"""Makes a checkerboard autostereogram.
Repetitions = (reps_horizontal, reps_vertical)
"""
checkerboard = np.zeros((horizontal_pattern * repetitions[0], vertical_pattern * repetitions[1]))
for i in range(checkerboard.shape[0]):
if (i // vertical_pattern) % 2 == 0:
checkerboard[i, :] = make_line(horizontal_pattern, repetitions[0])
else:
checkerboard[i, :] = make_line(horizontal_pattern, repetitions[0], with_dot=False)
return checkerboard
def make_line(pattern_size, repetitions, with_dot=True):
"""Makes a horizontal line."""
pattern = np.random.binomial(1, p=0.5, size=pattern_size)
line = np.concatenate([pattern for _ in range(repetitions)])
if with_dot:
for j in range(repetitions-1):
line[(j+1) * pattern_size] = np.random.binomial(1, p=0.5, size=1)
return line
pattern_size = 90
repetitions = 3
line = make_line(pattern_size, repetitions, with_dot=False)
line.shape
(270,)
plt.plot(line)
[<matplotlib.lines.Line2D at 0x1071972b0>]
checkerboard = make_checkerboard()
plt.figure(figsize=(15, 15))
plt.imshow(checkerboard, cmap='gray')
plt.axis('off')
(-0.5, 199.5, 199.5, -0.5)
def make_alternating_line():
"Makes an alternating line."
pattern = np.random.binomial(1, p=0.5, size=20)
line = np.empty([])
for block in range(10):
if block % 2 == 0:
line = np.append(line, pattern)
else:
line = np.append(line, np.r_[pattern, np.random.randint(2)])
return line
line = make_alternating_line()
plt.plot(line)
[<matplotlib.lines.Line2D at 0x10b9501d0>]
line.shape
(206,)
line_shape = line.size
checkerboard = np.c_[[make_alternating_line() for _ in range(206)]]
plt.figure(figsize=(15, 15))
plt.imshow(checkerboard, cmap='gray')
plt.axis('off')
(-0.5, 205.5, 205.5, -0.5)
def make_line():
pattern = np.random.binomial(1, p=0.5, size=40)
depth_map = (np.arange(200) / 20).astype(np.int) % 2
line = np.empty(depth_map.size)
for j in range(depth_map.size):
if j < pattern.size:
line[j] = pattern[j]
else:
lag = 80 + depth_map[j] * 20
line[j] = line[j - lag]
return line
checkerboard = np.c_[[make_line() for _ in range(200)]]
plt.figure(figsize=(15, 15))
plt.imshow(checkerboard, cmap='gray')
plt.axis('off')
(-0.5, 199.5, 199.5, -0.5)
The initial pattern needs to be large!
Let's just make a far plane background image.
pattern_size = 90
img_shape = (200, 200)
def make_pattern(pattern_size):
"Returns random dot pattern."
return np.random.binomial(1, 0.5, size=pattern_size)
lag = 72
far_plane = np.empty(img_shape)
for row in range(img_shape[0]):
pattern = make_pattern(pattern_size)
line = np.empty((img_shape[1]))
for c in np.arange(line.size):
if c < pattern_size:
line[c] = pattern[c]
else:
line[c] = line[c - lag]
far_plane[row, :] = line
plt.figure(figsize=(15, 15))
plt.imshow(far_plane, cmap='gray')
plt.axis('off')
(-0.5, 199.5, 199.5, -0.5)
Ok, this works. Let's now try the checkerboard.
far_lag = 80
near_lag = 70
n_squares = 6
dist = img_shape[0] // 10
checkerboard = np.empty(img_shape)
for row in range(img_shape[0]):
pattern = make_pattern(pattern_size)
line = np.empty((img_shape[1]))
for c in np.arange(line.size):
if c // dist % 2 == row // dist % 2:
lag = far_lag
else:
lag = near_lag
if c - lag < 0:
line[c] = pattern[(c - lag) % pattern_size]
else:
line[c] = line[c - lag]
checkerboard[row, :] = line
plt.figure(figsize=(15, 15))
plt.imshow(checkerboard, cmap='gray')
plt.axis('off')
(-0.5, 199.5, 199.5, -0.5)