File size: 5,233 Bytes
b17d851 cdf0064 b17d851 cdf0064 b17d851 cdf0064 b17d851 1010bf9 cdf0064 b17d851 cdf0064 b17d851 cdf0064 b17d851 cdf0064 b17d851 cdf0064 b17d851 cdf0064 b17d851 cdf0064 b17d851 cdf0064 b17d851 cdf0064 b17d851 cdf0064 b17d851 1010bf9 b17d851 cdf0064 b17d851 cdf0064 b17d851 cdf0064 b17d851 cdf0064 b17d851 | 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 | import os, sys, numpy as np, json, io, base64
os.environ["TF_ENABLE_ONEDNN_OPTS"] = "0"
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
from flask import Flask, render_template, request, jsonify
from PIL import Image
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "src"))
app = Flask(__name__)
app.config["MAX_CONTENT_LENGTH"] = 16 * 1024 * 1024
MODEL_PATH = "best_autoencoder_model.h5"
MODEL_INFO_PATH = "model_info.json"
SAMPLES_DIR = "test_images"
model = None
model_info = None
def load_trained_model():
global model
if not os.path.exists(MODEL_PATH):
print(f"Warning: {MODEL_PATH} not found")
return
import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D
try:
inp = Input(shape=(28, 28, 1))
x = Conv2D(32, (3, 3), activation="relu", padding="same")(inp)
x = MaxPooling2D((2, 2), padding="same")(x)
x = Conv2D(16, (3, 3), activation="relu", padding="same")(x)
enc = MaxPooling2D((2, 2), padding="same")(x)
x = Conv2D(16, (3, 3), activation="relu", padding="same")(enc)
x = UpSampling2D((2, 2))(x)
x = Conv2D(32, (3, 3), activation="relu", padding="same")(x)
x = UpSampling2D((2, 2))(x)
out = Conv2D(1, (3, 3), activation="sigmoid", padding="same")(x)
rebuilt = Model(inp, out)
rebuilt.load_weights(MODEL_PATH)
model = rebuilt
print("Model loaded via weights-only approach")
except Exception as e:
print(f"Model load failed: {e}")
def load_model_info():
global model_info
if os.path.exists(MODEL_INFO_PATH):
with open(MODEL_INFO_PATH) as f:
model_info = json.load(f)
else:
model_info = {
"model_name": "CNN Autoencoder",
"architecture": "Convolutional Autoencoder",
"test_accuracy": "N/A",
"test_f1_score": "N/A",
"test_loss": "N/A"
}
def preprocess_image(image):
img = image.convert("L").resize((28, 28))
arr = np.array(img) / 255.0
return arr.reshape(1, 28, 28, 1)
def array_to_base64(arr):
arr = arr.squeeze()
arr = (arr * 255).astype(np.uint8)
img = Image.fromarray(arr, mode="L")
buf = io.BytesIO()
img.save(buf, format="PNG")
return "data:image/png;base64," + base64.b64encode(buf.getvalue()).decode()
load_trained_model()
load_model_info()
@app.route("/")
def index():
return render_template("index.html", model_info=model_info)
@app.route("/api/model-info")
def get_model_info():
if model_info:
return jsonify(model_info)
return jsonify({"error": "not available"}), 404
@app.route("/api/samples")
def get_samples():
"""Return list of sample images as base64 thumbnails"""
samples = []
if os.path.exists(SAMPLES_DIR):
for fname in sorted(os.listdir(SAMPLES_DIR)):
if fname.lower().endswith((".png", ".jpg", ".jpeg")):
fpath = os.path.join(SAMPLES_DIR, fname)
with open(fpath, "rb") as f:
b64 = base64.b64encode(f.read()).decode()
# Parse label from filename e.g. noisy_digit_2_8.png -> Digit 2
parts = fname.replace(".png", "").split("_")
label = f"Digit {parts[2]}" if len(parts) >= 3 else fname
samples.append({
"filename": fname,
"label": label,
"thumbnail": f"data:image/png;base64,{b64}"
})
return jsonify(samples)
@app.route("/api/denoise-sample", methods=["POST"])
def denoise_sample():
"""Denoise a built-in sample image by filename"""
if model is None:
return jsonify({"error": "Model not loaded"}), 500
data = request.get_json()
filename = data.get("filename", "")
# Sanitize: only allow filenames, no path traversal
filename = os.path.basename(filename)
fpath = os.path.join(SAMPLES_DIR, filename)
if not os.path.exists(fpath):
return jsonify({"error": "Sample not found"}), 404
try:
image = Image.open(fpath)
proc = preprocess_image(image)
denoised = model.predict(proc, verbose=0)
return jsonify({"original": array_to_base64(proc), "denoised": array_to_base64(denoised)})
except Exception as e:
return jsonify({"error": str(e)}), 500
@app.route("/denoise", methods=["POST"])
def denoise():
if model is None:
return jsonify({"error": "Model not loaded"}), 500
if "image" not in request.files:
return jsonify({"error": "No image uploaded"}), 400
file = request.files["image"]
if not file.filename:
return jsonify({"error": "No image selected"}), 400
try:
image = Image.open(file.stream)
proc = preprocess_image(image)
denoised = model.predict(proc, verbose=0)
return jsonify({"original": array_to_base64(proc), "denoised": array_to_base64(denoised)})
except Exception as e:
return jsonify({"error": str(e)}), 500
if __name__ == "__main__":
port = int(os.environ.get("PORT", 7860))
app.run(debug=False, host="0.0.0.0", port=port)
|