Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated FaceRec/app/main/Edit.py #86

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
285 changes: 137 additions & 148 deletions FaceRec/app/main/Edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import requests
from flask import Blueprint
from flask import Response as flask_response
from flask import redirect, render_template, request
from flask import flash, g, redirect, render_template, request
from PIL import Image

from FaceRec.config import Config
Expand All @@ -21,191 +21,180 @@
static_folder="../../static/",
)

# Global variable for video capture
cap = cv2.VideoCapture(0)


# function for displaying live video
def display_live_video():
"""
Generator for displaying live video from the camera.
def initialize_camera():
"""Initialize the camera resource if it's not already opened."""
global cap
if not cap.isOpened():
cap.open(0)


def release_camera():
"""Release the camera resource when no longer needed."""
global cap
if cap.isOpened():
cap.release()


Yields frames as JPEG images.
"""
def validate_input(data: dict) -> bool:
"""Validates the input form data."""
if not data.get("EmployeeCode").isdigit():
flash("Invalid EmployeeCode. It should be numeric.")
return False
if not data.get("Name"):
flash("Name cannot be empty.")
return False
if not data.get("gender"):
flash("Gender cannot be empty.")
return False
if not data.get("Department"):
flash("Department cannot be empty.")
return False
return True


def display_live_video():
"""Generator for displaying live video from the camera."""
initialize_camera() # Ensure camera is initialized
while True:
success, frame = cap.read() # Read a frame from the camera
success, frame = cap.read()
if not success:
break
frame = cv2.flip(frame, 1)
ret, buffer = cv2.imencode(".jpg", frame)
frame = buffer.tobytes
if not ret:
break
yield (
b"--frame\r\n"
b"Content-Type: image/jpeg\r\n\r\n" +
bytearray(buffer) + b"\r\n\r\n"
b"Content-Type: image/jpeg\r\n\r\n" + buffer.tobytes() + b"\r\n\r\n"
)


# Route for displaying video
@Edit_blueprint.route("/video_feed")
def video_feed():
"""Route for displaying live video from the camera.

Returns a multipart response with a JPEG image for each frame from the camera.
"""
"""Route for displaying live video from the camera."""
return flask_response(
display_live_video(),
mimetype="multipart/x-mixed-replace;boundary=frame",
mimetype="multipart/x-mixed-replace; boundary=frame",
)


# Route for capturing image from video
@Edit_blueprint.route("/capture", methods=["GET", "POST"])
@Edit_blueprint.route("/capture", methods=["POST"])
def capture():
"""Route for capturing an image from the video feed.

This route is used to capture a single frame from the video feed and save it to a file.
The frame is flipped horizontally before saving.

The image is stored in a file specified by the `Config.image_data_file` variable.

The response is a redirect to the "Image" route, which displays the captured image.

The request is expected to be a POST request with the following form data:
- EmployeeCode: The employee code for the person in the image.
- Name: The name of the person in the image.
- gender: The gender of the person in the image.
- Department: The department of the person in the image.
"""
global EmployeeCode
global Name
global gender
global Dept
global encoded_image
EmployeeCode = request.form.get("EmployeeCode", "")
Name = request.form.get("Name", "")
gender = request.form.get("gender", "")
Dept = request.form.get("Department", "")
ret, frame = cap.read(True)
frame = cv2.flip(frame, 1)
_, buffer = cv2.imencode(".jpg", frame)
encoded_image = base64.b64encode(buffer).decode("utf-8")
with open(Config.image_data_file, "w") as file:
json.dump({"base64_image": encoded_image}, file)
"""Route for capturing an image from the video feed."""
form_data = {
"EmployeeCode": request.form.get("EmployeeCode", ""),
"Name": request.form.get("Name", ""),
"gender": request.form.get("gender", ""),
"Department": request.form.get("Department", ""),
}

if not validate_input(form_data):
return redirect("capture")

try:
initialize_camera() # Ensure camera is initialized
ret, frame = cap.read()
if not ret:
flash("Failed to capture the image.")
return redirect("capture")

frame = cv2.flip(frame, 1)
_, buffer = cv2.imencode(".jpg", frame)
encoded_image = base64.b64encode(buffer).decode("utf-8")

g.employee_data = form_data
g.encoded_image = encoded_image

with open(Config.image_data_file, "w") as file:
json.dump({"base64_image": encoded_image}, file)
except Exception as e:
flash(f"Error capturing image: {e}")
return redirect("capture")

return redirect("Image")


# Route to display captured image
@Edit_blueprint.route("/Image", methods=["GET"])
def display_image():
"""Route to display the captured image.

This route reads the image data from a file specified by the
`Config.image_data_file` variable and displays it in the template.

The image is saved to a file in the directory specified by the
`Config.upload_image_path` variable.

The most recent image is displayed.

The image is displayed in the template with the name "image_path".

Returns:
A rendered template with the image path.
"""
if os.path.exists(Config.image_data_file):
with open(Config.image_data_file) as file:
image_data = json.load(file)
encoded_image = image_data.get("base64_image", "")
decoded_image_data = base64.b64decode(encoded_image)
image = Image.open(io.BytesIO(decoded_image_data))
filename = "final.png"
image.save(
os.path.join(
Config.upload_image_path[0],
filename,
),
quality=100,
)
image = sorted(
os.listdir(Config.upload_image_path[0]),
key=lambda x: os.path.getatime(
os.path.join(Config.upload_image_path[0], x),
),
reverse=True,
)
if image:
recent_image = image[0]
image_path = os.path.join(Config.upload_image_path[0], recent_image)
else:
recent_image = None
image_path = os.path.join(Config.upload_image_path[0], recent_image)
print("done")
"""Route to display the captured image."""
try:
if os.path.exists(Config.image_data_file):
with open(Config.image_data_file) as file:
image_data = json.load(file)

encoded_image = image_data.get("base64_image", "")
decoded_image_data = base64.b64decode(encoded_image)
image = Image.open(io.BytesIO(decoded_image_data))

filename = "final.png"
image.save(os.path.join(
Config.upload_image_path[0], filename), quality=100)

image_files = sorted(
os.listdir(Config.upload_image_path[0]),
key=lambda x: os.path.getatime(
os.path.join(Config.upload_image_path[0], x)
),
reverse=True,
)
recent_image = image_files[0] if image_files else None
else:
recent_image = None
except Exception as e:
flash(f"Error loading image: {e}")
return render_template("index.html", image_path=None)

image_path = (
os.path.join(Config.upload_image_path[0], recent_image)
if recent_image
else None
)
return render_template("index.html", image_path=image_path)


@Edit_blueprint.route("/edit/<int:EmployeeCode>", methods=["POST", "GET"])
def edit(EmployeeCode):
"""Edit an existing employee.

This route allows users to edit an existing employee record. The
employee is identified by the EmployeeCode, which is a required
parameter.

The route accepts both GET and POST requests. A GET request will
retrieve the employee data from the database and display it in
the template. A POST request will update the employee data in the
database with the values provided in the form.

The form data is expected to contain the following fields:

- Name
- gender
- Department
"""Edit an existing employee."""
if request.method == "POST":
form_data = {
"Name": request.form["Name"],
"gender": request.form["Gender"],
"Department": request.form["Department"],
}

The image is expected to be stored in the `Config.image_data_file`
file.
if not validate_input(form_data):
return redirect(f"/edit/{EmployeeCode}")

The most recent image is displayed.
try:
with open(Config.image_data_file) as file:
image_data = json.load(file)

The image is displayed in the template with the name "image_path".
encoded_image = image_data.get("base64_image", "")
payload = {**form_data, "Image": encoded_image}

Returns:
A rendered template with the image path if the request is a
GET, or a redirect to the home page if the request is a POST.
"""
if request.method == "POST":
Name = request.form["Name"]
gender = request.form["Gender"]
Department = request.form["Department"]
with open(Config.image_data_file) as file:
image_data = json.load(file)
encoded_image = image_data.get("base64_image", "")
payload = {
"Name": Name,
"gender": gender,
"Department": Department,
"Image": encoded_image,
}
# logger.info(payload)
try:
url = requests.put(
f"http://127.0.0.1:8000/update/{EmployeeCode}",
json=payload,
response = requests.put(
f"http://127.0.0.1:8000/update/{EmployeeCode}", json=payload
)
url.status_code
# logger.info(url.json())

if response.status_code != 200:
flash(f"Failed to update employee: {response.status_code}")
return redirect("/")

except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
response = requests.get(f"http://127.0.0.1:8000/read/{EmployeeCode}")
# logger.info(response.status_code)
# logger.info(response.json())
if response.status_code == 200:
employee_data = response.json()
return render_template("edit.html", employee_data=employee_data)
else:
return f"Error {response.status_code}: Failed to retrieve employee data."
flash(f"Request failed: {e}")
return redirect(f"/edit/{EmployeeCode}")

try:
response = requests.get(f"http://127.0.0.1:8000/read/{EmployeeCode}")
if response.status_code == 200:
employee_data = response.json()
return render_template("edit.html", employee_data=employee_data)
else:
flash(
f"Error {response.status_code}: Failed to retrieve employee data.")
return render_template("edit.html", employee_data=None)
except requests.exceptions.RequestException as e:
flash(f"Error fetching employee data: {e}")
return render_template("edit.html", employee_data=None)
Loading