Last commit not found
raw
history blame
5.82 kB
import gradio as gr
from PIL import Image
import numpy as np
matrices = {
'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 ] ],
'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)
right = Image.fromarray(right_img)
# 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 copy of the left image to modify
result = left.copy()
# Get the pixel maps
width, height = left.size
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]
resultMap[x, y] = (
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]),
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]),
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])
)
# 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)
right = Image.fromarray(right_img)
# 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
leftMap = left.load()
rightMap = right.load()
# Create a new image twice as wide
pair = Image.new('RGB', (width * 2, height))
pairMap = pair.load()
# Copy the left and right images side by side
for y in range(0, height):
for x in range(0, width):
pairMap[x, y] = leftMap[x, y]
pairMap[x + width, y] = rightMap[x, y]
# 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(
["optimized", "true", "mono", "color", "halfcolor"],
label="Color Method",
value="optimized",
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:
- **optimized**: Best for most images (default)
- **true**: True color anaglyph
- **mono**: Monochrome output
- **color**: Full color (may cause ghosting)
- **halfcolor**: Balance between color and depth
""")
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()