Spaces:
Sleeping
Sleeping
File size: 5,861 Bytes
78018be 38536ee 78018be 620c68b 78018be 1a2e2b3 78018be 1a2e2b3 78018be 1a2e2b3 78018be 1a2e2b3 78018be 1a2e2b3 78018be 1a2e2b3 78018be 1a2e2b3 78018be 1a2e2b3 78018be 1a2e2b3 78018be 620c68b bb2c24a 620c68b 78018be 620c68b 78018be 620c68b 46f2bb1 a086fab 620c68b 46f2bb1 a086fab 788d388 5201bad 620c68b fd6ac71 620c68b fd6ac71 620c68b fd6ac71 1f76689 a086fab 695ba08 a086fab 695ba08 a086fab 695ba08 fd6ac71 620c68b fd6ac71 620c68b fd6ac71 | 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 160 161 162 163 164 165 166 167 | 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("""
<style>
html, body {
background-color: #eaf3fc;
font-family: 'Segoe UI', sans-serif;
}
.title {
font-size: 2.8rem;
font-weight: 800;
color: #005bb5;
text-align: center;
margin-bottom: 0.5rem;
letter-spacing: -1px;
}
.subtitle {
text-align: center;
font-size: 1.2rem;
color: #333;
margin-bottom: 2.5rem;
}
.stButton > button {
background-color: #005bb5;
color: white;
font-weight: bold;
border-radius: 10px;
padding: 0.75rem 2rem;
border: none;
font-size: 1rem;
transition: all 0.3s ease-in-out;
box-shadow: 0 4px 10px rgba(0, 91, 181, 0.2);
}
.stButton > button:hover {
background-color: #004494;
transform: scale(1.05);
}
.stDownloadButton > button {
background-color: #28a745;
color: white;
font-weight: bold;
border-radius: 10px;
padding: 0.75rem 2rem;
border: none;
font-size: 1rem;
transition: all 0.3s ease-in-out;
box-shadow: 0 4px 10px rgba(40, 167, 69, 0.2);
}
.stDownloadButton > button:hover {
background-color: #1e7e34;
transform: scale(1.05);
}
</style>
""", unsafe_allow_html=True)
# Titles
st.markdown('<div class="title">πΈ Image Augmentation Studio</div>', unsafe_allow_html=True)
st.markdown('<div class="subtitle">Upload an image, choose transformations, preview, and download your dataset!</div>', 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")
|