I am trying to create an image recogniton program and so far I have made the model and all of the actual AI aspect of things. However, when it came to implementing this into a website, I have been having lots of unexpected troubles when I'm trying to display a prediction on another web-page using Python Flask.
For instance, whenever I click on upload after choosing my image, it just opens a new web-page with the directory of the image and project files where I can navigate the files/folders. It should just be a container with the prediction and some text.
I am quite new to this style of programming so I'm not sure how to solve the bugs as of now, so any help would be greatly appreciated. I have linked a photo of the current project directory structure.
Here is my Python Flask code
@app.route('/')
def index():
return render_template('html/enter_p.html')
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return redirect(request.url)
file = request.files['file']
if file.filename == '':
return redirect(request.url)
if file:
# Save the file
file_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
file.save(file_path)
# Redirect to the prediction page
return redirect(url_for('predict', filename=file.filename))
@app.route('/predict/<filename>')
def predict(filename):
# Load your model and make a prediction
result = model.predict(os.path.join(app.config['UPLOAD_FOLDER'], filename)) # Replace with your prediction logic
return render_template('results.html', prediction=result, filename=filename)
if __name__ == '__main__':
app.run(debug=True)
Here is my results html code:
<div class="container">
<h1>Prediction Result: {{ prediction }}</h1>
<img src="{{ url_for('static', filename='uploads/' + filename) }}" alt="Uploaded Mole Image" width="300px">
<br>
And if necessary, here is my upload form:
<form action = "../static/uploads/" method = "post" enctype = "multipart/form-data">
<input type = "file" name = "file" accept = "image/*" required>
<button type = "submit">Upload</button>
</form>
I have changed your code slightly and combined the two routes index
and upload_file
into one. Since the form is now sent to the same address from which the form is retrieved, it is no longer necessary to set the action
attribute of the form.
Another advantage is that the lines redirect(request.url)
send a GET request to the address used, which is not possible with your POST variant because it does not accept GET.
from flask import (
Flask,
redirect,
render_template,
request,
url_for
)
import os
# ...
app = Flask(__name__)
app.config.from_mapping(
UPLOAD_FOLDER=os.path.join(app.static_folder, 'uploads')
)
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
if 'file' not in request.files:
return redirect(request.url)
file = request.files['file']
if file.filename == '':
return redirect(request.url)
if file:
# Save the file
file_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
file.save(file_path)
# Redirect to the prediction page
return redirect(url_for('predict', filename=file.filename))
return render_template('index.html')
@app.route('/predict/<path:filename>')
def predict(filename):
result = model.predict(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return render_template('results.html', prediction=result, filename=filename)
# ...
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Index</title>
</head>
<body>
<form method="POST" enctype="multipart/form-data">
<input type="file" name="file" accept="image/*" required>
<button type="submit">Upload</button>
</form>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Predict</title>
</head>
<body>
<div class="container">
<h1>Prediction Result: {{ prediction }}</h1>
<img src="{{ url_for('static', filename='uploads/' + filename) }}" alt="Uploaded Mole Image" width="300px">
<br>
<a href="{{ url_for('index') }}">Upload another image</a>
</div>
</body>
</html>