Spaces:
Sleeping
Sleeping
File size: 6,094 Bytes
aec5cde f7efd7b aec5cde f7efd7b aec5cde aa2570e aec5cde f118b28 aec5cde f7efd7b aec5cde f7efd7b aec5cde f118b28 aec5cde f7efd7b aec5cde f118b28 f7efd7b f118b28 f7efd7b f118b28 aa2570e aec5cde aa2570e f7efd7b aa2570e f7efd7b aa2570e f7efd7b aa2570e f7efd7b aa2570e aec5cde f118b28 aec5cde |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
import gradio as gr
from PIL import Image
import numpy as np
# Fixed matrices for proper red/cyan anaglyph viewing
matrices = {
# For true red/cyan anaglyphs, we need strict channel separation
'true': [ [ 1, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0, 0, 0, 1 ] ],
'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 ] ],
'color': [ [ 1, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0, 0, 0, 1 ] ],
'halfcolor': [ [ 0.299, 0.587, 0.114, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0, 0, 0, 1 ] ],
'optimized': [ [ 0, 0.7, 0.3, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0, 0, 0, 1 ] ],
}
def make_anaglyph(left_img, right_img, color_method):
"""Generate an anaglyph from left and right images using the specified color method"""
if left_img is None or right_img is None:
return None
# Convert from numpy array (from Gradio) to PIL Image
left = Image.fromarray(left_img).convert('RGB')
right = Image.fromarray(right_img).convert('RGB')
# Check if both images have the same dimensions
if left.size != right.size:
# Resize right image to match left image dimensions
right = right.resize(left.size, Image.LANCZOS)
# Create a new blank image to put the anaglyph into
width, height = left.size
result = Image.new('RGB', (width, height))
# Get the pixel maps
leftMap = left.load()
rightMap = right.load()
resultMap = result.load()
# Use the selected color matrix
m = matrices[color_method]
# Apply the anaglyph transformation
for y in range(0, height):
for x in range(0, width):
r1, g1, b1 = leftMap[x, y]
r2, g2, b2 = rightMap[x, y]
# Calculate new RGB values
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])
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])
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])
# Ensure values are in valid range
r = max(0, min(255, r))
g = max(0, min(255, g))
b = max(0, min(255, b))
resultMap[x, y] = (r, g, b)
# Convert back to numpy array for Gradio
return np.array(result)
def make_stereopair(left_img, right_img, color_method):
"""Generate a stereo pair from left and right images"""
if left_img is None or right_img is None:
return None
# Convert from numpy array (from Gradio) to PIL Image
left = Image.fromarray(left_img).convert('RGB')
right = Image.fromarray(right_img).convert('RGB')
# Check if both images have the same dimensions
if left.size != right.size:
# Resize right image to match left image dimensions
right = right.resize(left.size, Image.LANCZOS)
width, height = left.size
# Create a new image twice as wide
pair = Image.new('RGB', (width * 2, height))
# Paste the left and right images side by side
pair.paste(left, (0, 0))
pair.paste(right, (width, 0))
# Convert to monochrome if required
if color_method == 'mono':
pair = pair.convert('L')
# Convert back to numpy array for Gradio
return np.array(pair)
def process_images(left_img, right_img, method, color_method):
"""Process images based on the selected method"""
if method == "anaglyph":
return make_anaglyph(left_img, right_img, color_method)
elif method == "parallel":
return make_stereopair(left_img, right_img, color_method)
elif method == "crossed":
return make_stereopair(right_img, left_img, color_method)
return None
css="""
div#col-container{
margin: 0 auto;
max-width: 1340px;
}
"""
# Create the Gradio interface
with gr.Blocks(css=css) as app:
with gr.Column(elem_id="col-container"):
gr.Markdown("# 3D Anaglyph Image Generator")
gr.Markdown("Upload left and right images to create 3D images using different methods.")
with gr.Row():
with gr.Column():
with gr.Row():
with gr.Column():
left_input = gr.Image(label="Left Image")
with gr.Column():
right_input = gr.Image(label="Right Image")
method = gr.Radio(
["anaglyph", "parallel", "crossed"],
label="Method",
value="anaglyph",
info="Select the 3D image creation method"
)
color_method = gr.Radio(
["true", "color", "optimized", "halfcolor", "mono"],
label="Color Method",
value="true",
info="Select the color processing method"
)
generate_btn = gr.Button("Generate 3D Image", variant="primary")
gr.Markdown("""
### Methods:
- **anaglyph**: Creates a red-cyan 3D image (requires 3D glasses)
- **parallel**: Creates side-by-side images for parallel viewing
- **crossed**: Creates side-by-side images for cross-eyed viewing
### Color Methods:
- **true**: Pure red-cyan anaglyph (best for 3D glasses)
- **color**: Same as true for red-cyan glasses
- **optimized**: Better color perception but may cause ghosting
- **halfcolor**: Balance between color and depth
- **mono**: Monochrome output
""")
output = gr.Image(label="Generated 3D Anaglyph Image")
generate_btn.click(
fn=process_images,
inputs=[left_input, right_input, method, color_method],
outputs=output
)
# Launch the app
if __name__ == "__main__":
app.launch() |