Sandeep001122's picture
updated
4b60492
# 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()