import streamlit as st
import cv2
import numpy as np
import io
import zipfile
import random
# Page configuration
st.set_page_config(page_title="✨ Image Augmenter", layout="centered")
# Custom Styling
st.markdown("""
""", unsafe_allow_html=True)
# Titles
st.markdown('
📸 Image Augmentation Studio
', unsafe_allow_html=True)
st.markdown('Upload an image, choose transformations, preview, and download your dataset!
', unsafe_allow_html=True)
# File Upload
uploaded_file = st.file_uploader("📤 Upload an image", type=["jpg", "jpeg", "png"])
# Select transformations
transform_options = st.multiselect(
"🔄 Choose one or more transformations",
["Translation", "Cropping", "Shearing", "Rotation", "Scaling", "Grayscale", "Flip Horizontally", "Flip Vertically"],
default=["Rotation"]
)
st.write("you selected : " , transform_options)
# Number of images
count = st.number_input("📈 Number of images to generate", min_value=10, max_value=200, value=100, step=10)
# Transformation logic
def apply_transformation(image, options, count):
rows, cols = image.shape[:2]
transformed_images = []
for _ in range(count):
img_out = image.copy() # Always initialize
if not options:
transformed_images.append(img_out)
continue
for option in options:
if option == "Translation":
tx, ty = random.randint(-50, 50), random.randint(-50, 50)
M = np.float32([[1, 0, tx], [0, 1, ty]])
img_out = cv2.warpAffine(img_out, M, (cols, rows), borderMode=cv2.BORDER_REFLECT)
elif option == "Cropping":
x1 = random.randint(0, cols // 4)
y1 = random.randint(0, rows // 4)
x2 = random.randint(3 * cols // 4, cols)
y2 = random.randint(3 * rows // 4, rows)
cropped = img_out[y1:y2, x1:x2]
img_out = cv2.resize(cropped, (cols, rows))
elif option == "Shearing":
shear_factor = random.uniform(-0.3, 0.3)
M = np.float32([[1, shear_factor, 0], [shear_factor, 1, 0]])
img_out = cv2.warpAffine(img_out, M, (cols, rows), borderMode=cv2.BORDER_REFLECT)
elif option == "Rotation":
angle = random.randint(-45, 45)
center = (cols // 2, rows // 2)
M = cv2.getRotationMatrix2D(center, angle, 1.0)
img_out = cv2.warpAffine(img_out, M, (cols, rows), borderMode=cv2.BORDER_REFLECT)
elif option == "Scaling":
scale = random.uniform(0.5, 1.5)
resized = cv2.resize(img_out, None, fx=scale, fy=scale, interpolation=cv2.INTER_LINEAR)
img_out = cv2.resize(resized, (cols, rows))
elif option == "Grayscale":
gray = cv2.cvtColor(img_out, cv2.COLOR_BGR2GRAY)
img_out = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
elif option == "Flip Horizontally":
img_out = cv2.flip(img_out, 1)
elif option == "Flip Vertically":
img_out = cv2.flip(img_out, 0)
transformed_images.append(img_out)
return transformed_images
# Main logic
if uploaded_file:
file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
image = cv2.imdecode(file_bytes, 1)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
st.image(image_rgb, caption="📷 Original Image", use_container_width=True)
if st.button("✨ Generate Augmented Images"):
with st.spinner("Generating images..."):
augmented_images = apply_transformation(image, transform_options, count)
st.markdown("### 🔍 Preview of Augmented Images")
cols_preview = st.columns(3)
for i in range(min(3, len(augmented_images))):
preview = cv2.cvtColor(augmented_images[i], cv2.COLOR_BGR2RGB)
cols_preview[i].image(preview, use_container_width=True)
zip_buffer = io.BytesIO()
with zipfile.ZipFile(zip_buffer, "w") as zip_file:
for idx, img in enumerate(augmented_images):
_, buffer = cv2.imencode(".png", img)
zip_file.writestr(f"augmented_{idx+1}.png", buffer.tobytes())
zip_buffer.seek(0)
st.success(f"✅ {count} Augmented Images Generated!")
st.download_button("📁 Download ZIP", zip_buffer, "augmented_images.zip", "application/zip")