import streamlit as st from PIL import Image, ImageOps import numpy as np import io # Custom CSS for styling st.markdown(""" """, unsafe_allow_html=True) # App title st.title("๐ŸŒŸ Interactive Image Augmentation Tool") # Sidebar: Upload image uploaded_image = st.sidebar.file_uploader("๐Ÿ“ค Upload an Image", type=["jpg", "png", "jpeg"]) if uploaded_image: # Open and display the uploaded image image = Image.open(uploaded_image) st.sidebar.image(image, caption="๐Ÿ“ธ Uploaded Image",width=400) # Sidebar: Augmentation options st.sidebar.header("โœจ Augmentation Options") augmentation_options = st.sidebar.multiselect( "Choose augmentations:", ["Cropping", "Flipping", "Rotation", "Zoom In", "Zoom Out", "Translation", "Shearing"] ) # Sidebar: Live preview toggle live_preview = st.sidebar.checkbox("๐Ÿ”„ Enable Live Preview", value=True) # Make a copy of the image for augmentation augmented_image = image.copy() # Apply augmentations based on user selections for option in augmentation_options: if option == "Cropping": left = st.sidebar.slider("Left Crop", 0, image.width // 2, 0) top = st.sidebar.slider("Top Crop", 0, image.height // 2, 0) right = st.sidebar.slider("Right Crop", 0, image.width // 2, 0) bottom = st.sidebar.slider("Bottom Crop", 0, image.height // 2, 0) augmented_image = augmented_image.crop((left, top, image.width - right, image.height - bottom)) elif option == "Flipping": flip_type = st.sidebar.selectbox("๐Ÿ”„ Flip Type", ["Horizontal", "Vertical"]) if flip_type == "Horizontal": augmented_image = ImageOps.mirror(augmented_image) elif flip_type == "Vertical": augmented_image = ImageOps.flip(augmented_image) elif option == "Rotation": angle = st.sidebar.slider("โคพ Rotation Angle (ยฐ)", 0, 360, 0) augmented_image = augmented_image.rotate(angle, expand=True) elif option == "Zoom In": zoom_factor = st.sidebar.slider("๐Ÿ” Zoom In Factor (%)", 100, 200, 100) / 100.0 width, height = augmented_image.size new_width = int(width * zoom_factor) new_height = int(height * zoom_factor) resized_image = augmented_image.resize((new_width, new_height)) augmented_image = resized_image.crop(((new_width - width) // 2, (new_height - height) // 2, (new_width + width) // 2, (new_height + height) // 2)) elif option == "Zoom Out": zoom_factor = st.sidebar.slider("๐Ÿ”Ž Zoom Out Factor (%)", 50, 100, 100) / 100.0 width, height = augmented_image.size new_width = int(width * zoom_factor) new_height = int(height * zoom_factor) resized_image = augmented_image.resize((new_width, new_height)) padded_image = Image.new("RGB", (width, height), (0, 0, 0)) padded_image.paste(resized_image, ((width - new_width) // 2, (height - new_height) // 2)) augmented_image = padded_image elif option == "Translation": x_shift = st.sidebar.slider("โ†” Horizontal Shift (Pixels)", -100, 100, 0) y_shift = st.sidebar.slider("โ†• Vertical Shift (Pixels)", -100, 100, 0) translation_matrix = (1, 0, x_shift, 0, 1, y_shift) augmented_image = augmented_image.transform(augmented_image.size, Image.AFFINE, translation_matrix, fillcolor=(0, 0, 0)) elif option == "Shearing": shear_angle = st.sidebar.slider("๐ŸŒ€ Shear Angle (ยฐ)", -45, 45, 0) shear_matrix = (1, np.tan(np.radians(shear_angle)), 0, 0, 1, 0) augmented_image = augmented_image.transform( (augmented_image.width + abs(int(augmented_image.height * np.tan(np.radians(shear_angle)))), augmented_image.height), Image.AFFINE, shear_matrix, fillcolor=(0, 0, 0) ) # Display the augmented image st.subheader("๐Ÿ–ผ๏ธ Augmented Image") st.image(augmented_image, caption="Augmented Output",width=400) # Download button for the augmented image buffer = io.BytesIO() augmented_image.save(buffer, format="PNG") buffer.seek(0) st.download_button("๐Ÿ“ฅ Download Augmented Image", buffer, file_name="augmented_image.png") else: st.sidebar.warning("๐Ÿ“‚ Please upload an image to get started!")