File size: 5,816 Bytes
aec5cde aa2570e aec5cde aa2570e aec5cde f118b28 aec5cde aa2570e aec5cde f118b28 aec5cde aa2570e aec5cde f118b28 aa2570e f118b28 aa2570e f118b28 aa2570e f118b28 aa2570e f118b28 aa2570e aec5cde 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 |
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() |