|
import gradio as gr |
|
import cv2 |
|
import numpy as np |
|
|
|
|
|
|
|
|
|
def process_images(image_files, crop, y_start, y_end, x_start, x_end): |
|
if not image_files: |
|
return "No images uploaded.", None |
|
|
|
|
|
extracted_images = [] |
|
for item in image_files: |
|
if isinstance(item, tuple): |
|
|
|
img = item[0] |
|
else: |
|
|
|
img = item |
|
|
|
|
|
if img is not None and isinstance(img, np.ndarray): |
|
extracted_images.append(img) |
|
|
|
|
|
if not extracted_images: |
|
return "No valid images found for stitching.", None |
|
|
|
try: |
|
|
|
if crop: |
|
crop_coords = (int(y_start), int(y_end), int(x_start), int(x_end)) |
|
else: |
|
crop_coords = None |
|
|
|
|
|
stitcher = cv2.Stitcher_create() |
|
|
|
|
|
status, panorama = stitcher.stitch(extracted_images) |
|
|
|
if status != cv2.Stitcher_OK: |
|
raise RuntimeError(f"Stitching failed with status code {status}.") |
|
|
|
if crop: |
|
y_start, y_end, x_start, x_end = crop_coords |
|
cropped_panorama = panorama[y_start:y_end, x_start:x_end] |
|
return panorama, cropped_panorama |
|
|
|
return panorama, None |
|
|
|
except Exception as e: |
|
|
|
raise gr.Error(f"Error during stitching: {str(e)}") |
|
|
|
|
|
|
|
with gr.Blocks(title="Creating Panorama using OpenCV") as demo: |
|
gr.Markdown("# Creating Panorama using OpenCV") |
|
gr.Markdown("Upload the series of images sequentially and get the perfect Panorama!") |
|
|
|
with gr.Row(equal_height=True): |
|
with gr.Column(): |
|
image_upload = gr.Gallery( |
|
columns=4, |
|
label="Upload Images", |
|
file_types=["image"], |
|
format="jpeg", |
|
type="numpy", |
|
) |
|
crop_checkbox = gr.Checkbox(label="Apply Cropping to Panorama", value=False) |
|
with gr.Row(): |
|
y_start = gr.Number(label="Crop Y Start", value=90, interactive=True) |
|
y_end = gr.Number(label="Crop Y End", value=867, interactive=True) |
|
with gr.Row(): |
|
x_start = gr.Number(label="Crop X Start", value=1, interactive=True) |
|
x_end = gr.Number(label="Crop X End", value=2000, interactive=True) |
|
stitch_button = gr.Button("Stitch Images") |
|
with gr.Row(): |
|
with gr.Column(): |
|
stitched_output = gr.Image(label="Stitched Panorama") |
|
cropped_output = gr.Image(label="Cropped Panorama") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def toggle_crop_inputs(crop): |
|
return gr.update(visible=crop), gr.update(visible=crop), gr.update(visible=crop), gr.update(visible=crop) |
|
|
|
crop_checkbox.change(fn=toggle_crop_inputs, inputs=[crop_checkbox], outputs=[y_start, y_end, x_start, x_end]) |
|
|
|
|
|
stitch_button.click( |
|
fn=process_images, |
|
inputs=[image_upload, crop_checkbox, y_start, y_end, x_start, x_end], |
|
outputs=[stitched_output, cropped_output], |
|
) |
|
|
|
gr.Markdown( |
|
""" |
|
**Note**: |
|
- Ensure that the uploaded images have overlapping regions for successful stitching. |
|
- Cropping coordinates should be within the dimensions of the stitched panorama. |
|
""" |
|
) |
|
|
|
|
|
demo.launch(show_error=True) |
|
|