svd_processor / app.py
binaychandra's picture
try resolving path issues
1f21b17
raw
history blame
5.52 kB
from flask import Flask, render_template, request, jsonify, send_from_directory
import numpy as np
from PIL import Image
import io
import base64
from scipy.linalg import svd
import os
app = Flask(__name__, static_folder='static', static_url_path='/static')
def calculate_storage(shape, r_value):
if len(shape) == 3: # RGB image
height, width, channels = shape
original_size = height * width * channels
compressed_size = channels * (height * r_value + r_value + width * r_value)
else: # Grayscale image
height, width = shape
original_size = height * width
compressed_size = height * r_value + r_value + width * r_value
return {
'original': original_size,
'compressed': compressed_size,
'compression_ratio': original_size / compressed_size if compressed_size > 0 else 0
}
def process_image(image_data, r_value):
# Open image as RGB
img = Image.open(io.BytesIO(image_data))
img_array = np.array(img)
# Check if image is RGB (3 channels)
if len(img_array.shape) == 3 and img_array.shape[2] == 3:
# Process each channel separately
reconstructed = np.zeros_like(img_array)
for channel in range(3):
# Extract the channel
channel_data = img_array[:, :, channel]
# Perform SVD on this channel
U, s, Vt = svd(channel_data, full_matrices=False)
# Reconstruct image with r singular values
r = min(r_value, len(s))
reconstructed[:, :, channel] = np.dot(U[:, :r] * s[:r], Vt[:r, :])
# Clip values to valid range and convert to uint8
reconstructed = np.clip(reconstructed, 0, 255).astype(np.uint8)
else:
# Fallback to grayscale processing if not RGB
img_array = np.array(img.convert('L'))
U, s, Vt = svd(img_array, full_matrices=False)
r = min(r_value, len(s))
reconstructed = np.dot(U[:, :r] * s[:r], Vt[:r, :])
reconstructed = np.clip(reconstructed, 0, 255).astype(np.uint8)
# Convert back to image
reconstructed_img = Image.fromarray(reconstructed)
# Save to base64 string
buffered = io.BytesIO()
reconstructed_img.save(buffered, format="PNG")
img_str = base64.b64encode(buffered.getvalue()).decode()
# Calculate storage requirements
storage = calculate_storage(img_array.shape, r_value)
return {
'processed_image': img_str,
'dimensions': img_array.shape,
'max_r': min(img_array.shape[0], img_array.shape[1]),
'storage': storage
}
def get_predefined_images():
images_dir = os.path.join('static', 'images')
if not os.path.exists(images_dir):
return []
allowed_extensions = {'.jpg', '.jpeg', '.png', '.gif'}
images = []
for filename in os.listdir(images_dir):
if os.path.splitext(filename)[1].lower() in allowed_extensions:
images.append({
'name': os.path.splitext(filename)[0].replace('_', ' ').title(),
'path': f'/static/images/{filename}'
})
return images
@app.route('/')
def index():
predefined_images = get_predefined_images()
return render_template('index.html', predefined_images=predefined_images)
@app.route('/process', methods=['POST'])
def process():
try:
image_data = None
if 'image' in request.files:
image = request.files['image'].read()
image_data = image
elif 'image_url' in request.form:
image_url = request.form['image_url']
if image_url.startswith('/static/'):
# Get relative path within static folder
rel_path = image_url[len('/static/'):]
image_path = os.path.join(app.static_folder, rel_path)
# Debug info
app.logger.info(f"Trying to access image at: {image_path}")
app.logger.info(f"File exists: {os.path.exists(image_path)}")
if os.path.exists(image_path):
with open(image_path, 'rb') as f:
image_data = f.read()
else:
# Try alternative path resolution
alt_path = os.path.join(os.getcwd(), 'static', rel_path)
app.logger.info(f"Trying alternative path: {alt_path}")
app.logger.info(f"File exists: {os.path.exists(alt_path)}")
if os.path.exists(alt_path):
with open(alt_path, 'rb') as f:
image_data = f.read()
else:
return jsonify({
'error': f'Image file not found. Tried paths: {image_path}, {alt_path}'
}), 404
if not image_data:
return jsonify({'error': 'No image provided'}), 400
r_value = int(request.form.get('r_value', 1))
result = process_image(image_data, r_value)
return jsonify(result)
except Exception as e:
import traceback
app.logger.error(f"Error processing image: {str(e)}")
app.logger.error(traceback.format_exc())
return jsonify({
'error': f'Error processing image: {str(e)}',
'traceback': traceback.format_exc()
}), 500
if __name__ == '__main__':
app.run(debug=True)