Spaces:
Build error
Build error
# python -m pip install --upgrade pip | |
import streamlit as st | |
import numpy as np | |
import matplotlib.pyplot as plt | |
import tensorflow as tf | |
import math | |
from PIL import Image | |
from io import BytesIO | |
import urllib.request | |
st.markdown( | |
f""" | |
<h1 style='text-align: center;'>Image Transformation using SVD</h1> | |
""", | |
unsafe_allow_html=True | |
) | |
st.markdown( | |
f""" | |
<h4 style='text-align: right; text-color: green'>By: Karan Bhardwaj, Sandeep Patel</h4> | |
""", | |
unsafe_allow_html=True) | |
st.write("<hr>", unsafe_allow_html=True) | |
st.markdown( | |
f""" | |
<p style='text-align: left; text-color: black'>This app uses a 2x2 matrix and transform(scale and rotation) a given 2D image accordingly using Single Value Decomposition Technique.</p> | |
""", | |
unsafe_allow_html=True) | |
st.write("<hr>", unsafe_allow_html=True) | |
st.subheader("2x2 Matrix Input") | |
# Create input fields for each element of the matrix | |
a11 = st.number_input("Enter element (1, 1)", value=3) | |
a12 = st.number_input("Enter element (1, 2)", value=0) | |
a21 = st.number_input("Enter element (2, 1)", value=4) | |
a22 = st.number_input("Enter element (2, 2)", value=5) | |
# Create a 2x2 matrix using the input values | |
matrix = np.array([[a11, a12], [a21, a22]]) | |
# Display the matrix | |
st.subheader("Your Matrix is:") | |
st.write(matrix) | |
#Test-1 A unit circle | |
# Create a unit circle | |
def unit_circle(): | |
theta = np.linspace(0, 2*np.pi, 100) | |
x = np.cos(theta) | |
y = np.sin(theta) | |
return np.vstack((x, y)) | |
#Test-2 Using URL | |
def image_api(): | |
# Load MNIST dataset | |
mnist = tf.keras.datasets.mnist | |
# Split the dataset into training and testing sets | |
(x_train, y_train), (x_test, y_test) = mnist.load_data() | |
# Normalize the pixel values of the images | |
x_train, x_test = x_train / 255.0, x_test / 255.0 | |
return x_train[np.random.randint(0, 100)].reshape(2, 392) | |
def unit_square(x): | |
if abs(x)==1: | |
return 0 | |
else: | |
return 1 | |
def square(): | |
x = np.linspace(-1,1,100) | |
y1 = np.vectorize(unit_square)(x) | |
y2 = -np.vectorize(unit_square)(x) | |
y = np.stack((y1, y2)).flatten() | |
x = np.stack((x, x)).flatten() | |
return [x,y] | |
# Test 3 Random matrix | |
def random_matrix(): | |
return np.random.rand(2, 100) | |
# Select one of the test image | |
lst = ['Unit Circle', 'Unit Square','MNIST Image', 'Random matrix'] | |
selected = st.selectbox("Select image option", lst) | |
st.subheader(f"You selected:- {selected}") | |
st.write("<hr>", unsafe_allow_html=True) | |
functions = [unit_circle, square,image_api, random_matrix] | |
flag = 0 | |
for i in range(4): | |
if lst[i]==selected: | |
circle = functions[i] | |
if circle == square: | |
flag = 1 | |
break | |
circle = circle() | |
# st.title("Image Transformation", text_align = 'center') | |
st.markdown( | |
f""" | |
<h1 style='text-align: center;'>Image Transformation</h1> | |
""", | |
unsafe_allow_html=True | |
) | |
# Create a scaling matrix | |
A = matrix #As input | |
axis_limit = [-8,8] | |
# Perform SVD on the scaling matrix | |
U, s, Vt = np.linalg.svd(A) | |
horizontal_scale_factor,vertical_scale_factor = s[0], s[1] | |
clockwise_angle = math.degrees(math.acos(Vt[0][0])) | |
anticlockwise_angle = math.degrees(math.acos(U[0][0])) | |
s = np.diag(s) | |
# Stage 1>>>>> Clockwise rotation | |
right_rot = Vt @ circle | |
# Stage 2 >>>>> Horizontal and vertical Scaling | |
scale_right_rot = s @ right_rot | |
#Stage 3 >>>>> Anticlock wise rotation | |
ellipse = U @ scale_right_rot | |
fig, ((ax1, ax2),(ax3,ax4)) = plt.subplots(2, 2, figsize=(10, 10), subplot_kw={'aspect': 'equal'}) | |
fig.suptitle('Transformation using SVD') | |
ax1.grid(True) | |
ax2.grid(True) | |
ax3.grid(True) | |
ax4.grid(True) | |
if flag==0: | |
# Plot circle | |
ax1.plot(circle[0],circle[1]) | |
ax1.set_xlim(axis_limit) | |
ax1.set_ylim(axis_limit) | |
ax1.set_title('Stage-1-Original Image') | |
# Indicating point P | |
x = circle[0, 30] # x-coordinate of the point | |
y = circle[1, 30] # y-coordinate of the point | |
ax1.plot(x, y, 'ro') # plot the point | |
ax1.text(x+0.05, y+0.05, 'P') # add the label | |
# ax1.axis('equal') | |
# Indicating Point Q | |
x = circle[0, 50] # x-coordinate of the point | |
y = circle[1, 50] # y-coordinate of the point | |
ax1.plot(x, y, 'o',color = 'green') # plot the point | |
ax1.text(x+0.1, y+0.1, 'Q') # add the label | |
# Stage 1>>>> Plot clockwise rotated circle | |
ax2.plot(right_rot[0],right_rot[1]) | |
ax2.set_xlim(axis_limit) | |
ax2.set_ylim(axis_limit) | |
# ax2.axis('equal') | |
ax2.set_title('Stage-2 Clockwise rotation') | |
ax2.text(axis_limit[0]+0.4, axis_limit[1]-1, f'Clockwise rotation Angle(in degree) = {clockwise_angle}') | |
# Corresponding point P | |
x = right_rot[0, 30] | |
y = right_rot[1, 30] | |
ax2.plot(x, y, 'ro') | |
ax2.text(x+0.05, y+0.05, 'P') | |
# ax1.axis('equal') | |
# Corresponding point Q | |
x = right_rot[0, 50] | |
y = right_rot[1, 50] | |
ax2.plot(x, y, 'o',color = 'green') | |
ax2.text(x+0.1, y+0.1, 'Q') | |
# Stage 2>>>> Horizontal/Verticale scaling | |
ax3.plot(scale_right_rot[0],scale_right_rot[1]) | |
ax3.set_xlim(axis_limit) | |
ax3.set_ylim(axis_limit) | |
# ax3.axis('equal') | |
ax3.set_title('Stage-3 Scaling') | |
ax3.text(axis_limit[0]+0.4, axis_limit[1]-1, f'Horizotal Scale factor = { round(horizontal_scale_factor, 2)}') | |
ax3.text(axis_limit[0]+0.4, axis_limit[1]-2, f'Vertical Scale factor = { round(vertical_scale_factor, 2)}') | |
# # Corresponding point P | |
x = scale_right_rot[0, 30] | |
y = scale_right_rot[1, 30] | |
ax3.plot(x, y, 'ro') | |
ax3.text(x+0.05, y+0.05, 'P') | |
# ax1.axis('equal') | |
# Corresponding point Q | |
x = scale_right_rot[0, 50] | |
y = scale_right_rot[1, 50] | |
ax3.plot(x, y, 'o',color = 'green') | |
ax3.text(x+0.1, y+0.1, 'Q') | |
# Stage 3>>>>>> Anticlockwise rotation | |
ax4.plot(ellipse[0], ellipse[1]) | |
ax4.set_xlim(axis_limit) | |
ax4.set_ylim(axis_limit) | |
# ax4.axis('equal') | |
ax4.set_title('Stage-4 Anticlockwise rotation') | |
ax4.text(axis_limit[0]+0.4, axis_limit[1]-1, f'Anti Clockwise rotation Angle(in degree) = {round(anticlockwise_angle, 2) }') | |
# ax4.ylim(-2,2) | |
# ax4.show() | |
# Corresponding point P | |
x = ellipse[0, 30] | |
y = ellipse[1, 30] | |
ax4.plot(x, y, 'ro') | |
ax4.text(x+0.05, y+0.05, 'P') | |
# ax1.axis('equal') | |
# Corresponding point Q | |
x = ellipse[0, 50] | |
y = ellipse[1, 50] | |
ax4.plot(x, y, 'o',color = 'tab:green') | |
ax4.text(x+0.1, y+0.1, 'Q') | |
else: | |
# Plot circle | |
ax1.plot(circle[0],circle[1], 'r', alpha = 0.5) | |
ax1.set_xlim(axis_limit) | |
ax1.set_ylim(axis_limit) | |
ax1.set_title('Stage-1-Original Image') | |
# Stage 1>>>> Plot clockwise rotated circle | |
ax2.plot(right_rot[0],right_rot[1], 'r', alpha = 0.5) | |
ax2.set_xlim(axis_limit) | |
ax2.set_ylim(axis_limit) | |
# ax2.axis('equal') | |
ax2.set_title('Stage-2 Clockwise rotation') | |
ax2.text(axis_limit[0]+0.4, axis_limit[1]-1, f'Clockwise rotation Angle(in degree) = {clockwise_angle}') | |
# Stage 2>>>> Horizontal/Verticale scaling | |
ax3.plot(scale_right_rot[0],scale_right_rot[1], 'r', alpha = 0.5) | |
ax3.set_xlim(axis_limit) | |
ax3.set_ylim(axis_limit) | |
# ax3.axis('equal') | |
ax3.set_title('Stage-3 Scaling') | |
ax3.text(axis_limit[0]+0.4, axis_limit[1]-1, f'Horizotal Scale factor = { round(horizontal_scale_factor, 2)}') | |
ax3.text(axis_limit[0]+0.4, axis_limit[1]-2, f'Vertical Scale factor = { round(vertical_scale_factor, 2)}') | |
# Stage 3>>>>>> Anticlockwise rotation | |
ax4.plot(ellipse[0],ellipse[1], 'r') | |
ax4.set_xlim(axis_limit) | |
ax4.set_ylim(axis_limit) | |
# ax4.axis('equal') | |
ax4.set_title('Stage-4 Anticlockwise rotation') | |
ax4.text(axis_limit[0]+0.4, axis_limit[1]-1, f'Anti Clockwise rotation Angle(in degree) = {round(anticlockwise_angle, 2) }') | |
# ax4.ylim(-2,2) | |
# ax4.show() | |
image = st.pyplot(fig) | |
if st.button('Save Image'): | |
# Save the plot to a file | |
fig.savefig('saved_plot.png') | |
st.write("<hr>", unsafe_allow_html=True) | |
file = open("discription.md", "r") | |
st.markdown(file.read()) | |
file.close() |