I don't understand what is wrong in my code. What the following code is trying to do is that when the user clicks "submit" (1) it makes a directory out of the uploaded files with directory name given by user, and then (2) take the training picture and predict who the picture is of then (3) displays the predicted picture. I get the following errors:
127.0.0.1 - - [03/Sep/2021 10:57:42] "GET / HTTP/1.1" 200 - 127.0.0.1 - - [03/Sep/2021 10:57:42] "GET /display/ HTTP/1.1" 404 - 127.0.0.1 - - [03/Sep/2021 10:57:53] "POST /predict HTTP/1.1" 302 - 127.0.0.1 - - [03/Sep/2021 10:57:53] "GET /predict HTTP/1.1" 405 -
app.py
import os
from flask import Flask, flash, request, redirect, render_template, url_for, send_file
import flask
from werkzeug.utils import secure_filename
import fcr_cv
from fcr_cv import fcr
app = Flask(__name__)
app.secret_key = "secret key"
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
# # Get current path
# path = os.getcwd()
# # file Upload
# UPLOAD_FOLDER = os.path.join(path, 'uploads')
# Make directory if uploads is not exists
# if not os.path.isdir(UPLOAD_FOLDER):
# os.mkdir(UPLOAD_FOLDER)
# app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# Allowed extension you can set your own
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def validate_input(request: flask.Request):
input = {}
try:
input["sample"] = request.files.getlist('sample')
input["test"] = request.files.get("test")
input["folder"] = request.form["folder"]
# allowed_file
except Exception as e:
print(e)
return False, input
return True, input
@app.route('/predict', methods=['POST'])
def predict():
if request.method == 'POST':
if 'sample' not in request.files:
flash('No file part')
return redirect(request.url)
if 'test' not in request.files:
flash('No test part')
return redirect(request.url)
is_valid, input = validate_input(request)
if not is_valid:
flash('Invalid input')
return redirect(request.url)
files = input["sample"]
for file in files:
data = input["folder"]
path = os.path.join("uploads", data)
os.makedirs(path, exist_ok=True)
app.config["UPLOAD_FOLDER"] = path
file.save(os.path.join(app.config['UPLOAD_FOLDER'], file.filename))
file = input["test"]
test_filepath = os.path.join("uploads", "test_image.jpg")
file.save(test_filepath)
target_image = fcr_cv.fcr(path, app.config["UPLOAD_FOLDER"])
flash('Image successfully uploaded and displayed below')
return redirect(request.url, filename=target_image)
else:
flash('Allowed image types are -> png, jpg, jpeg, gif')
return redirect(request.url)
@app.route('/')
def upload_form():
return render_template('upload.html')
@app.route('/display/<filename>')
def cv_display_image(filename):
print(filename)
#print('display_image filename: ' + filename)
return send_file(os.path.join("uploads", filename), mimetype='image/jpeg')
if __name__ == "__main__":
app.run()
upload.html
<html>
<body>
<title>Python Flask Multiple Files Upload Example</title>
<h2>Select file(s) to upload</h2>
<form class="form" form action="{{ url_for('predict') }}" method="POST">
<div class="row">
<p class="label">Sample files</p>
<input class="input" type="file" name="sample" multiple="true" autocomplete="off" required>
</div>
<div class="row">
<p class="label">Folder Name</p>
<input type="text" name="folder" required>
</div>
<div class="row">
<p class="label">Training File</p>
<input class="input" type="file" name="test" multiple="false" autocomplete="off" required>
</div>
<input type="submit" name="submit" value="Predict">
<div>
<img src="{{ url_for('cv_display_image', filename=filename) }}">
</div>
</form>
</html>
</body>
fcr_cv.py
#import imutils
from imutils import paths
import face_recognition
import pickle
import cv2
import os
import time
from matplotlib import pyplot as plt
#import uploadfiles
#from uploadfiles import app
#UPLOAD_FOLDER = 'uploads/'
#UPLOAD_FOLDER = uploadfiles.upload_file()
#get paths of each file in folder named Images
#Images here contains my data(folders of various persons)`
#app = Flask(__name__)
def fcr(path, UPLOAD_FOLDER):
imagePaths = list(paths.list_images((UPLOAD_FOLDER)))
knownEncodings = []
knownNames = []
# loop over the image paths
for (i, imagePath) in enumerate(imagePaths):
# extract the person name from the image path
print(imagePath)
name = imagePath.split(os.path.sep)[-1]
# load the input image and convert it from BGR (OpenCV ordering)
# to dlib ordering (RGB)
image = cv2.imread(imagePath)
rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
#Use Face_recognition to locate faces
boxes = face_recognition.face_locations(rgb,model='hog')
# compute the facial embedding for the face
encodings = face_recognition.face_encodings(rgb, boxes)
# loop over the encodings
for encoding in encodings:
knownEncodings.append(encoding)
knownNames.append(name)
#save emcodings along with their names in dictionary data
data = {"encodings": knownEncodings, "names": knownNames}
#print(data)
#use pickle to save data into a file for later use
f = open("face_enc", "wb")
f.write(pickle.dumps(data))
f.close()
#find path of xml file containing haarcascade file
cascPathface = os.path.dirname(cv2.__file__) + "/data/haarcascade_frontalface_alt2.xml"
# load the harcaascade in the cascade classifier
faceCascade = cv2.CascadeClassifier(cascPathface)
# load the known faces and embeddings saved in last file
data = pickle.loads(open('face_enc', "rb").read())
# image = cv2.imread('test/aj4.jpeg')
image = cv2.imread(path)
#cv2.imshow("Frame", image)
#print(image)
rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
#convert image to Greyscale for haarcascade
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(60, 60),
flags=cv2.CASCADE_SCALE_IMAGE)
encodings = face_recognition.face_encodings(rgb)
names = []
# loop over the facial embeddings incase
# we have multiple embeddings for multiple fcaes
for encoding in encodings:
#Compare encodings with encodings in data["encodings"]
#Matches contain array with boolean values and True for the embeddings it matches closely
#and False for rest
matches = face_recognition.compare_faces(data["encodings"],
encoding)
#set name =inknown if no encoding matches
name = "Unknown"
# check to see if we have found a match
if True in matches:
#Find positions at which we get True and store them
matchedIdxs = [i for (i, b) in enumerate(matches) if b]
counts = {}
# loop over the matched indexes and maintain a count for
# each recognized face face
for i in matchedIdxs:
#Check the names at respective indexes we stored in matchedIdxs
name = data["names"][i]
#increase count for the name we got
counts[name] = counts.get(name, 0) + 1
#set name which has highest count
name = max(counts, key=counts.get)
# update the list of names
names.append(name)
#print(xyz)
# loop over the recognized faces
for ((x, y, w, h), name) in zip(faces, names):
# rescale the face coordinates
# Window name in which image is displayed
#window_name = 'image'
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(image, name, (x, y), cv2.FONT_HERSHEY_SIMPLEX,
0.75, (0, 255, 0), 2)
# plt.figure(image)
# plt.imshow(image)
#plt.axis('off') # if you want to remove coordinates
#data = random.random((5,5))
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
#image.set_cmap('hot')
plt.axis('off')
cv2.imwrite('./uploads/target_image', image)
return "target_image"
# plt.savefig("test.png", bbox_inches='tight')
# cv2.show()
# cv2.imshow("Frame", image)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
# cv2.waitKey(1)
#fcr('test/aj1.jpeg','uploads/')