Skip to content

Commit 32d07eb

Browse files
committed
Offset exponent parameter for stereo image generation
Preparing to change the algo again...
1 parent d7a8fd1 commit 32d07eb

File tree

4 files changed

+21
-12
lines changed

4 files changed

+21
-12
lines changed

src/common_constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def __init__(self, default_value=None, *args):
3636
STEREO_DIVERGENCE = 2.5
3737
STEREO_SEPARATION = 0.0
3838
STEREO_FILL_ALGO = "polylines_sharp"
39+
STEREO_OFFSET_EXPONENT = 2.0
3940
STEREO_BALANCE = 0.0
4041

4142
GEN_NORMALMAP = False

src/common_ui.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ def main_ui_panel(is_depth_tab):
8989
choices=['none', 'naive', 'naive_interpolating', 'polylines_soft',
9090
'polylines_sharp'],
9191
type="value")
92+
inp += go.STEREO_OFFSET_EXPONENT, gr.Slider(label="Magic exponent", minimum=1, maximum=2, step=1)
9293
inp += go.STEREO_BALANCE, gr.Slider(minimum=-1.0, maximum=1.0, step=0.05,
9394
label='Balance between eyes')
9495

src/core.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ def core_generation_funnel(outpath, inputimages, inputdepthmaps, inputnames, inp
215215
stereoimages = create_stereoimages(
216216
inputimages[count], img_output,
217217
inp[go.STEREO_DIVERGENCE], inp[go.STEREO_SEPARATION],
218-
inp[go.STEREO_MODES], inp[go.STEREO_BALANCE], inp[go.STEREO_FILL_ALGO])
218+
inp[go.STEREO_MODES],
219+
inp[go.STEREO_BALANCE], inp[go.STEREO_OFFSET_EXPONENT], inp[go.STEREO_FILL_ALGO])
219220
for c in range(0, len(stereoimages)):
220221
yield count, inp[go.STEREO_MODES][c], stereoimages[c]
221222

src/stereoimage_generation.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ def Inner(func): return lambda *args, **kwargs: func(*args, **kwargs)
1010
from PIL import Image
1111

1212

13-
def create_stereoimages(original_image, depthmap, divergence, separation=0.0, modes=None, stereo_balance=0.0,
14-
fill_technique='polylines_sharp'):
13+
def create_stereoimages(original_image, depthmap, divergence, separation=0.0, modes=None,
14+
stereo_balance=0.0, stereo_offset_exponent=1.0, fill_technique='polylines_sharp'):
1515
"""Creates stereoscopic images.
1616
An effort is made to make them look nice, but beware that the resulting image will have some distortion.
1717
The correctness was not rigorously tested.
@@ -28,6 +28,8 @@ def create_stereoimages(original_image, depthmap, divergence, separation=0.0, mo
2828
Some of the supported modes are: 'left-right', 'right-left', 'top-bottom', 'bottom-top', 'red-cyan-anaglyph'.
2929
:param float stereo_balance: has to do with how the divergence will be split among the two parts of the image,
3030
must be in the [-1.0; 1.0] interval.
31+
:param float stereo_offset_exponent: Higher values move objects residing
32+
between close and far plane more to the far plane
3133
:param str fill_technique: applying divergence inevitably creates some gaps in the image.
3234
This parameter specifies the technique that will be used to fill in the blanks in the two resulting images.
3335
Must be one of the following: 'none', 'naive', 'naive_interpolating', 'polylines_soft', 'polylines_sharp'.
@@ -42,9 +44,11 @@ def create_stereoimages(original_image, depthmap, divergence, separation=0.0, mo
4244
original_image = np.asarray(original_image)
4345
balance = (stereo_balance + 1) / 2
4446
left_eye = original_image if balance < 0.001 else \
45-
apply_stereo_divergence(original_image, depthmap, +1 * divergence * balance, -1 * separation, fill_technique)
47+
apply_stereo_divergence(original_image, depthmap, +1 * divergence * balance, -1 * separation,
48+
stereo_offset_exponent, fill_technique)
4649
right_eye = original_image if balance > 0.999 else \
47-
apply_stereo_divergence(original_image, depthmap, -1 * divergence * (1 - balance), separation, fill_technique)
50+
apply_stereo_divergence(original_image, depthmap, -1 * divergence * (1 - balance), separation,
51+
stereo_offset_exponent, fill_technique)
4852

4953
results = []
5054
for mode in modes:
@@ -70,7 +74,7 @@ def create_stereoimages(original_image, depthmap, divergence, separation=0.0, mo
7074
return [Image.fromarray(r) for r in results]
7175

7276

73-
def apply_stereo_divergence(original_image, depth, divergence, separation, fill_technique):
77+
def apply_stereo_divergence(original_image, depth, divergence, separation, stereo_offset_exponent, fill_technique):
7478
depth_min = depth.min()
7579
depth_max = depth.max()
7680
normalized_depth = (depth - depth_min) / (depth_max - depth_min)
@@ -79,17 +83,18 @@ def apply_stereo_divergence(original_image, depth, divergence, separation, fill_
7983

8084
if fill_technique in ['none', 'naive', 'naive_interpolating']:
8185
return apply_stereo_divergence_naive(
82-
original_image, normalized_depth, divergence_px, separation_px, fill_technique
86+
original_image, normalized_depth, divergence_px, separation_px, stereo_offset_exponent, fill_technique
8387
)
8488
if fill_technique in ['polylines_soft', 'polylines_sharp']:
8589
return apply_stereo_divergence_polylines(
86-
original_image, normalized_depth, divergence_px, separation_px, fill_technique
90+
original_image, normalized_depth, divergence_px, separation_px, stereo_offset_exponent, fill_technique
8791
)
8892

8993

9094
@njit(parallel=False)
9195
def apply_stereo_divergence_naive(
92-
original_image, normalized_depth, divergence_px: float, separation_px: float, fill_technique):
96+
original_image, normalized_depth, divergence_px: float, separation_px: float, stereo_offset_exponent: float,
97+
fill_technique: str):
9398
h, w, c = original_image.shape
9499

95100
derived_image = np.zeros_like(original_image)
@@ -99,7 +104,7 @@ def apply_stereo_divergence_naive(
99104
# Swipe order should ensure that pixels that are closer overwrite
100105
# (at their destination) pixels that are less close
101106
for col in range(w) if divergence_px < 0 else range(w - 1, -1, -1):
102-
col_d = col + int((normalized_depth[row][col] ** 2) * divergence_px + separation_px)
107+
col_d = col + int((normalized_depth[row][col] ** stereo_offset_exponent) * divergence_px + separation_px)
103108
if 0 <= col_d < w:
104109
derived_image[row][col_d] = original_image[row][col]
105110
filled[row * w + col_d] = 1
@@ -155,7 +160,8 @@ def apply_stereo_divergence_naive(
155160

156161
@njit(parallel=True) # fastmath=True does not reasonably improve performance
157162
def apply_stereo_divergence_polylines(
158-
original_image, normalized_depth, divergence_px: float, separation_px: float, fill_technique):
163+
original_image, normalized_depth, divergence_px: float, separation_px: float, stereo_offset_exponent: float,
164+
fill_technique: str):
159165
# This code treats rows of the image as polylines
160166
# It generates polylines, morphs them (applies divergence) to them, and then rasterizes them
161167
EPSILON = 1e-7
@@ -172,7 +178,7 @@ def apply_stereo_divergence_polylines(
172178
pt[pt_end] = [-1.0 * w, 0.0, 0.0]
173179
pt_end += 1
174180
for col in range(0, w):
175-
coord_d = (normalized_depth[row][col] ** 2) * divergence_px
181+
coord_d = (normalized_depth[row][col] ** stereo_offset_exponent) * divergence_px
176182
coord_x = col + 0.5 + coord_d + separation_px
177183
if PIXEL_HALF_WIDTH < EPSILON:
178184
pt[pt_end] = [coord_x, abs(coord_d), col]

0 commit comments

Comments
 (0)