fffiloni commited on
Commit
360ecaa
·
verified ·
1 Parent(s): 07b7070

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +75 -71
app.py CHANGED
@@ -2,12 +2,14 @@ import gradio as gr
2
  from PIL import Image
3
  import numpy as np
4
 
 
5
  matrices = {
6
- 'true': [ [ 0.299, 0.587, 0.114, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0.299, 0.587, 0.114 ] ],
 
7
  'mono': [ [ 0.299, 0.587, 0.114, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0.299, 0.587, 0.114, 0.299, 0.587, 0.114 ] ],
8
  'color': [ [ 1, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0, 0, 0, 1 ] ],
9
  'halfcolor': [ [ 0.299, 0.587, 0.114, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0, 0, 0, 1 ] ],
10
- 'optimized': [ [ 0, 0.7, 0.3, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0, 0, 0, 1 ] ],
11
  }
12
 
13
  def make_anaglyph(left_img, right_img, color_method):
@@ -16,8 +18,8 @@ def make_anaglyph(left_img, right_img, color_method):
16
  return None
17
 
18
  # Convert from numpy array (from Gradio) to PIL Image
19
- left = Image.fromarray(left_img)
20
- right = Image.fromarray(right_img)
21
 
22
  # Check if both images have the same dimensions
23
  if left.size != right.size:
@@ -41,11 +43,24 @@ def make_anaglyph(left_img, right_img, color_method):
41
  for x in range(0, width):
42
  r1, g1, b1 = leftMap[x, y]
43
  r2, g2, b2 = rightMap[x, y]
44
- resultMap[x, y] = (
45
- int(r1*m[0][0] + g1*m[0][1] + b1*m[0][2] + r2*m[1][0] + g2*m[1][1] + b2*m[1][2]),
46
- int(r1*m[0][3] + g1*m[0][4] + b1*m[0][5] + r2*m[1][3] + g2*m[1][4] + b2*m[1][5]),
47
- int(r1*m[0][6] + g1*m[0][7] + b1*m[0][8] + r2*m[1][6] + g2*m[1][7] + b2*m[1][8])
48
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
  # Convert back to numpy array for Gradio
51
  return np.array(result)
@@ -56,8 +71,8 @@ def make_stereopair(left_img, right_img, color_method):
56
  return None
57
 
58
  # Convert from numpy array (from Gradio) to PIL Image
59
- left = Image.fromarray(left_img)
60
- right = Image.fromarray(right_img)
61
 
62
  # Check if both images have the same dimensions
63
  if left.size != right.size:
@@ -65,18 +80,13 @@ def make_stereopair(left_img, right_img, color_method):
65
  right = right.resize(left.size, Image.LANCZOS)
66
 
67
  width, height = left.size
68
- leftMap = left.load()
69
- rightMap = right.load()
70
 
71
  # Create a new image twice as wide
72
  pair = Image.new('RGB', (width * 2, height))
73
- pairMap = pair.load()
74
 
75
- # Copy the left and right images side by side
76
- for y in range(0, height):
77
- for x in range(0, width):
78
- pairMap[x, y] = leftMap[x, y]
79
- pairMap[x + width, y] = rightMap[x, y]
80
 
81
  # Convert to monochrome if required
82
  if color_method == 'mono':
@@ -95,59 +105,53 @@ def process_images(left_img, right_img, method, color_method):
95
  return make_stereopair(right_img, left_img, color_method)
96
  return None
97
 
98
- css="""
99
- div#col-container{
100
- margin: 0 auto;
101
- max-width: 1340px;
102
- }
103
- """
104
  # Create the Gradio interface
105
- with gr.Blocks(css=css) as app:
106
- with gr.Column(elem_id="col-container"):
107
- gr.Markdown("# 3D Anaglyph Image Generator")
108
- gr.Markdown("Upload left and right images to create 3D images using different methods.")
109
-
110
- with gr.Row():
111
- with gr.Column():
112
-
113
- with gr.Row():
114
- with gr.Column():
115
- left_input = gr.Image(label="Left Image")
116
- with gr.Column():
117
- right_input = gr.Image(label="Right Image")
118
-
119
- method = gr.Radio(
120
- ["anaglyph", "parallel", "crossed"],
121
- label="Method",
122
- value="anaglyph",
123
- info="Select the 3D image creation method"
124
- )
125
-
126
- color_method = gr.Radio(
127
- ["optimized", "true", "mono", "color", "halfcolor"],
128
- label="Color Method",
129
- value="optimized",
130
- info="Select the color processing method"
131
- )
132
-
133
- generate_btn = gr.Button("Generate 3D Image", variant="primary")
134
-
135
- gr.Markdown("""
136
- ### Methods:
137
- - **anaglyph**: Creates a red-cyan 3D image (requires 3D glasses)
138
- - **parallel**: Creates side-by-side images for parallel viewing
139
- - **crossed**: Creates side-by-side images for cross-eyed viewing
140
-
141
- ### Color Methods:
142
- - **optimized**: Best for most images (default)
143
- - **true**: True color anaglyph
144
- - **mono**: Monochrome output
145
- - **color**: Full color (may cause ghosting)
146
- - **halfcolor**: Balance between color and depth
147
- """)
148
-
149
- output = gr.Image(label="Generated 3D Anaglyph Image")
150
-
151
  generate_btn.click(
152
  fn=process_images,
153
  inputs=[left_input, right_input, method, color_method],
 
2
  from PIL import Image
3
  import numpy as np
4
 
5
+ # Modified matrices for proper red/cyan anaglyph viewing
6
  matrices = {
7
+ # Red channel from left image, green/blue channels from right image
8
+ 'true': [ [ 1, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0, 0, 0, 1 ] ],
9
  'mono': [ [ 0.299, 0.587, 0.114, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0.299, 0.587, 0.114, 0.299, 0.587, 0.114 ] ],
10
  'color': [ [ 1, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0, 0, 0, 1 ] ],
11
  'halfcolor': [ [ 0.299, 0.587, 0.114, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0, 0, 0, 1 ] ],
12
+ 'optimized': [ [ 0.7, 0.3, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0, 0, 0, 1 ] ],
13
  }
14
 
15
  def make_anaglyph(left_img, right_img, color_method):
 
18
  return None
19
 
20
  # Convert from numpy array (from Gradio) to PIL Image
21
+ left = Image.fromarray(left_img).convert('RGB')
22
+ right = Image.fromarray(right_img).convert('RGB')
23
 
24
  # Check if both images have the same dimensions
25
  if left.size != right.size:
 
43
  for x in range(0, width):
44
  r1, g1, b1 = leftMap[x, y]
45
  r2, g2, b2 = rightMap[x, y]
46
+
47
+ # Calculate new RGB values
48
+ r = int(r1*m[0][0] + g1*m[0][1] + b1*m[0][2] + r2*m[1][0] + g2*m[1][1] + b2*m[1][2])
49
+ g = int(r1*m[0][3] + g1*m[0][4] + b1*m[0][5] + r2*m[1][3] + g2*m[1][4] + b2*m[1][5])
50
+ b = int(r1*m[0][6] + g1*m[0][7] + b1*m[0][8] + r2*m[1][6] + g2*m[1][7] + b2*m[1][8])
51
+
52
+ # For true red/cyan anaglyph experience, ensure pure colors
53
+ if color_method == 'color' or color_method == 'true':
54
+ # Ensure pure red from left image (no green or blue)
55
+ g = 0 if r > 0 else g
56
+ b = 0 if r > 0 else b
57
+
58
+ # Clamp values to valid range
59
+ r = max(0, min(255, r))
60
+ g = max(0, min(255, g))
61
+ b = max(0, min(255, b))
62
+
63
+ resultMap[x, y] = (r, g, b)
64
 
65
  # Convert back to numpy array for Gradio
66
  return np.array(result)
 
71
  return None
72
 
73
  # Convert from numpy array (from Gradio) to PIL Image
74
+ left = Image.fromarray(left_img).convert('RGB')
75
+ right = Image.fromarray(right_img).convert('RGB')
76
 
77
  # Check if both images have the same dimensions
78
  if left.size != right.size:
 
80
  right = right.resize(left.size, Image.LANCZOS)
81
 
82
  width, height = left.size
 
 
83
 
84
  # Create a new image twice as wide
85
  pair = Image.new('RGB', (width * 2, height))
 
86
 
87
+ # Paste the left and right images side by side
88
+ pair.paste(left, (0, 0))
89
+ pair.paste(right, (width, 0))
 
 
90
 
91
  # Convert to monochrome if required
92
  if color_method == 'mono':
 
105
  return make_stereopair(right_img, left_img, color_method)
106
  return None
107
 
 
 
 
 
 
 
108
  # Create the Gradio interface
109
+ with gr.Blocks(title="3D Image Generator") as app:
110
+ gr.Markdown("# 3D Image Generator")
111
+ gr.Markdown("Upload left and right images to create 3D images using different methods.")
112
+
113
+ with gr.Row():
114
+ with gr.Column():
115
+ left_input = gr.Image(label="Left Image")
116
+ with gr.Column():
117
+ right_input = gr.Image(label="Right Image")
118
+
119
+ with gr.Row():
120
+ with gr.Column():
121
+ method = gr.Radio(
122
+ ["anaglyph", "parallel", "crossed"],
123
+ label="Method",
124
+ value="anaglyph",
125
+ info="Select the 3D image creation method"
126
+ )
127
+ with gr.Column():
128
+ color_method = gr.Radio(
129
+ ["true", "color", "optimized", "halfcolor", "mono"],
130
+ label="Color Method",
131
+ value="true",
132
+ info="Select the color processing method"
133
+ )
134
+
135
+ generate_btn = gr.Button("Generate 3D Image", variant="primary")
136
+
137
+ output = gr.Image(label="Generated 3D Image")
138
+
139
+ gr.Markdown("""
140
+ ### Methods:
141
+ - **anaglyph**: Creates a red-cyan 3D image (requires 3D glasses)
142
+ - **parallel**: Creates side-by-side images for parallel viewing
143
+ - **crossed**: Creates side-by-side images for cross-eyed viewing
144
+
145
+ ### Color Methods for Anaglyphs:
146
+ - **true**: Pure red-cyan anaglyph (best for 3D glasses, recommended)
147
+ - **color**: Full color anaglyph with pure red-cyan separation
148
+ - **optimized**: Balanced color and depth perception
149
+ - **halfcolor**: Preserves some color while maintaining depth
150
+ - **mono**: Monochrome output
151
+
152
+ For best results with red-cyan glasses, use 'true' or 'color' methods.
153
+ """)
154
+
155
  generate_btn.click(
156
  fn=process_images,
157
  inputs=[left_input, right_input, method, color_method],