skip to Main Content

I am working on a personal project of mine, which is a face detect web app using python and flask.
The issue is after performing the face detection on an image it doesn’t return that image correctly.
When I check the folder that stores the result image, the image is there but can’t seem to figure out why it isn’t showing on the webpage.

Here is my code
app.py:

#imports
from flask import Flask
from flask import render_template, request, redirect, url_for
from flask_wtf import FlaskForm
from wtforms import FileField, SubmitField
from werkzeug.utils import secure_filename
import os
import cv2


app = Flask(__name__)
app.static_folder = "Styles"
app.config['SECRET_KEY'] = 'super'
app.config['UPLOAD_FOLDER'] = 'static/files'

# form class definition
class UploadFileForm(FlaskForm):
    file = FileField("File")
    submit = SubmitField("Detect Faces")

@app.route("/home", methods=["GET", "POST"])
def homePage():
    form = UploadFileForm()
    
    if form.validate_on_submit():
        file = form.file.data
        if file:
            filename = secure_filename(file.filename)
            filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
             # Make sure the directory exists
            os.makedirs(os.path.dirname(filepath), exist_ok=True)
            
            # Print filepath for debugging
            print("Filepath:", filepath)
            
            file.save(filepath)
            
            # Perform face detection on the uploaded image using OpenCV
            image = cv2.imread(filepath)
            gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
            face_data = cv2.CascadeClassifier('AI Face Detector App Projecthaarcascade_frontalface_default.xml')
            detected_faces = face_data.detectMultiScale(gray_image)

            # Draw rectangles around the detected faces
            for (x, y, w, h) in detected_faces:
                cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 10)
            
            # Save the image with detected faces
            result_path = os.path.join(app.config['UPLOAD_FOLDER'], 'result_' + filename)
            cv2.imwrite(result_path, image)

    

            return render_template('results.html', result_path=result_path)
    
    return render_template("index.html", form=form)

if __name__ == '__main__':
    app.run(debug=True)

index.html:

<!DOCTYPE html>
<html>
  <head>
    <title>Face Detection App</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

  </head>
  <body>
    <div class="entire-webpage">
      <h1>
        Welcome to the Face Detector app!
      </h1>
      <div>
        To detect faces, you can import a Photo, Video, or use your computer's webcam to detect a face.
      </div>

      <div>
        <form method="POST" enctype="multipart/form-data">
          {{form.hidden_tag() }}
          {{form.file() }}
          {{form.submit() }}
        </form>
      </div>

      <div class="owner-label">
        <p>
          Created by Omoze
        </p>

      </div>

    </div>

   
  </body>
</html>

results.html

<!DOCTYPE html>
<html>
<head>
    <title>Face Detection Results</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='result.css') }}">
</head>
<body>
    <div class="result-page">
        <h1>Detected Faces</h1>
        <img class="phote-result" src="{{ url_for('static', filename=result_path) }}" >
    </div>
    

</body>
</html>

Result:
Input
Result

I tried using CSS to try to modify the size of the image to see if that would do anything but nothing so far

results.css

body {
    background-color: rgb(72, 158, 125);
}


.result-page {
    
    text-align: center;
}

.phot-result {
    width: 100%;
}

p {
    padding-top: 600px;    
}

2

Answers


  1. Chosen as BEST ANSWER

    Figured out a workaround. I used the base64 module to encode the image to be able to display using this code:

      # Encode the image to base64 to display directly in HTML
      with open(result_path, "rb") as img_file:
          img_data = base64.b64encode(img_file.read()).decode("utf-8")
    
      return render_template('results.html', img_data=img_data)
    

  2. flask by default looks for images in the /static folder, it looks like you are passing the arg static/files/result_xyz.png to the img tag and the flask appends another static folder on the start, making it <img src="static/static/files/result_xyz.png"..., try changing it to:

    return render_template('results.html', result_path=f'files/{filename}')

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search