From 848295ae5f56b9487b62a20b906f7e78fc6674c9 Mon Sep 17 00:00:00 2001 From: dev2 Date: Sun, 23 Jun 2024 18:25:16 +0000 Subject: [PATCH] st1 --- .gitignore | 2 + app.py | 7 +- app2.py | 80 ++++++++++ app3.py | 84 ++++++++++ app4.py | 93 +++++++++++ app5.py | 81 ++++++++++ app6.py | 86 +++++++++++ bin/Activate.ps1 | 247 ++++++++++++++++++++++++++++++ bin/activate | 69 +++++++++ bin/activate.csh | 26 ++++ bin/activate.fish | 69 +++++++++ bin/f2py | 8 + bin/face_detection | 8 + bin/face_recognition | 8 + bin/flask | 8 + bin/pip | 8 + bin/pip3 | 8 + bin/pip3.10 | 8 + bin/python | 1 + bin/python3 | 1 + bin/python3.10 | 1 + pyvenv.cfg | 3 + requirements.txt | 5 + student_encodings.pkl | Bin 0 -> 1183 bytes students_data.pkl | Bin 0 -> 5548 bytes templates/upload.html | 18 +++ upload.py | 29 ++++ uploads/1111111111/1719166994.jpg | Bin 0 -> 10048 bytes uploads/3333/1719166349.jpg | Bin 0 -> 8672 bytes 29 files changed, 955 insertions(+), 3 deletions(-) create mode 100644 .gitignore create mode 100644 app2.py create mode 100644 app3.py create mode 100644 app4.py create mode 100644 app5.py create mode 100644 app6.py create mode 100644 bin/Activate.ps1 create mode 100755 bin/activate create mode 100755 bin/activate.csh create mode 100644 bin/activate.fish create mode 100755 bin/f2py create mode 100755 bin/face_detection create mode 100755 bin/face_recognition create mode 100755 bin/flask create mode 100755 bin/pip create mode 100755 bin/pip3 create mode 100755 bin/pip3.10 create mode 120000 bin/python create mode 120000 bin/python3 create mode 120000 bin/python3.10 create mode 100644 pyvenv.cfg create mode 100644 requirements.txt create mode 100644 student_encodings.pkl create mode 100644 students_data.pkl create mode 100644 templates/upload.html create mode 100644 upload.py create mode 100644 uploads/1111111111/1719166994.jpg create mode 100644 uploads/3333/1719166349.jpg diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a6665a7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +lib +lib64 diff --git a/app.py b/app.py index c28b91d..927470c 100644 --- a/app.py +++ b/app.py @@ -1,4 +1,4 @@ -from flask import Flask, request, jsonify +from flask import Flask, request, jsonify, render_template, send_from_directory, make_response from flask_cors import CORS import face_recognition import os @@ -23,7 +23,7 @@ if os.path.exists(STUDENT_ENCODINGS_FILE): else: student_encodings = {} -@app.route('/upload_images', methods=['POST']) +@app.route('/upload', methods=['POST']) def upload_images(): student_id = request.form.get('student_id') if 'images' not in request.files or not student_id: @@ -33,6 +33,7 @@ def upload_images(): encodings = [] for image in images: + image_path = os.path.join(STUDENT_IMAGES_DIR, f"{student_id}_{image.filename}") image.save(image_path) @@ -73,4 +74,4 @@ def recognize(): return jsonify({"error": "No face found in the uploaded image"}), 400 if __name__ == '__main__': - app.run(debug=True) + app.run(debug=True, host="0.0.0.0", port=5005) diff --git a/app2.py b/app2.py new file mode 100644 index 0000000..d491081 --- /dev/null +++ b/app2.py @@ -0,0 +1,80 @@ +from flask import Flask, request, jsonify, render_template, send_from_directory, make_response +from flask_restful import Api, Resource +import os +import face_recognition +from werkzeug.utils import secure_filename +from PIL import Image +import numpy as np + +app = Flask(__name__) +api = Api(app) + +UPLOAD_FOLDER = 'upload' +if not os.path.exists(UPLOAD_FOLDER): + os.makedirs(UPLOAD_FOLDER) + +app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER + +# Helper function to save image +def save_image(image, roll_number): + roll_number_folder = os.path.join(app.config['UPLOAD_FOLDER'], roll_number) + if not os.path.exists(roll_number_folder): + os.makedirs(roll_number_folder) + image_count = len(os.listdir(roll_number_folder)) + 1 + image_path = os.path.join(roll_number_folder, f"{image_count}.jpg") + image.save(image_path) + return image_path + +# Helper function to load known faces +def load_known_faces(): + known_faces = [] + known_roll_numbers = [] + for roll_number in os.listdir(app.config['UPLOAD_FOLDER']): + roll_number_folder = os.path.join(app.config['UPLOAD_FOLDER'], roll_number) + for filename in os.listdir(roll_number_folder): + image_path = os.path.join(roll_number_folder, filename) + image = face_recognition.load_image_file(image_path) + encodings = face_recognition.face_encodings(image) + if encodings: + known_faces.append(encodings[0]) + known_roll_numbers.append(roll_number) + return known_faces, known_roll_numbers + +class UploadImage(Resource): + def post(self): + roll_number = request.form['roll_number'] + if 'image' not in request.files: + return jsonify({"error": "No image provided"}), 400 + image = request.files['image'] + filename = secure_filename(image.filename) + image = Image.open(image) + image_path = save_image(image, roll_number) + return jsonify({"message": f"Image saved as {image_path}"}), 200 + +class RecognizeStudent(Resource): + def post(self): + if 'image' not in request.files: + return jsonify({"error": "No image provided"}), 400 + image = request.files['image'] + filename = secure_filename(image.filename) + image = face_recognition.load_image_file(image) + unknown_encodings = face_recognition.face_encodings(image) + if not unknown_encodings: + return jsonify({"error": "No faces found in the image"}), 400 + unknown_encoding = unknown_encodings[0] + + known_faces, known_roll_numbers = load_known_faces() + results = face_recognition.compare_faces(known_faces, unknown_encoding) + + if True in results: + matched_index = results.index(True) + roll_number = known_roll_numbers[matched_index] + return jsonify({"roll_number": roll_number}), 200 + else: + return jsonify({"error": "No matching student found"}), 404 + +api.add_resource(UploadImage, '/upload') +api.add_resource(RecognizeStudent, '/recognize') + +if __name__ == '__main__': + app.run(debug=True, host="0.0.0.0", port=5005) diff --git a/app3.py b/app3.py new file mode 100644 index 0000000..93a0028 --- /dev/null +++ b/app3.py @@ -0,0 +1,84 @@ +from flask import Flask, request, jsonify, render_template, send_from_directory, make_response +from flask_restful import Api, Resource +import os +import face_recognition +from werkzeug.utils import secure_filename +from PIL import Image +import numpy as np + +app = Flask(__name__) +api = Api(app) + +UPLOAD_FOLDER = 'upload' +if not os.path.exists(UPLOAD_FOLDER): + os.makedirs(UPLOAD_FOLDER) + +app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER + +# Helper function to save image +def save_image(image, roll_number): + roll_number_folder = os.path.join(app.config['UPLOAD_FOLDER'], roll_number) + if not os.path.exists(roll_number_folder): + os.makedirs(roll_number_folder) + image_count = len(os.listdir(roll_number_folder)) + 1 + image_path = os.path.join(roll_number_folder, f"{image_count}.jpg") + image.save(image_path) + return image_path + +# Helper function to load known faces +def load_known_faces(): + known_faces = [] + known_roll_numbers = [] + for roll_number in os.listdir(app.config['UPLOAD_FOLDER']): + roll_number_folder = os.path.join(app.config['UPLOAD_FOLDER'], roll_number) + for filename in os.listdir(roll_number_folder): + image_path = os.path.join(roll_number_folder, filename) + image = face_recognition.load_image_file(image_path) + encodings = face_recognition.face_encodings(image) + if encodings: + known_faces.append(encodings[0]) + known_roll_numbers.append(roll_number) + return known_faces, known_roll_numbers + +@app.route('/') +def index(): + return render_template('./upload.html') + +class UploadImage(Resource): + def post(self): + roll_number = request.form['roll_number'] + if 'image' not in request.files: + return jsonify({"error": "No image provided"}), 400 + image = request.files['image'] + filename = secure_filename(image.filename) + image = Image.open(image) + image_path = save_image(image, roll_number) + return jsonify({"message": f"Image saved as {image_path}"}), 200 + +class RecognizeStudent(Resource): + def post(self): + if 'image' not in request.files: + return jsonify({"error": "No image provided"}), 400 + image = request.files['image'] + filename = secure_filename(image.filename) + image = face_recognition.load_image_file(image) + unknown_encodings = face_recognition.face_encodings(image) + if not unknown_encodings: + return jsonify({"error": "No faces found in the image"}), 400 + unknown_encoding = unknown_encodings[0] + + known_faces, known_roll_numbers = load_known_faces() + results = face_recognition.compare_faces(known_faces, unknown_encoding) + + if True in results: + matched_index = results.index(True) + roll_number = known_roll_numbers[matched_index] + return jsonify({"roll_number": roll_number}), 200 + else: + return jsonify({"error": "No matching student found"}), 404 + +api.add_resource(UploadImage, '/upload') +api.add_resource(RecognizeStudent, '/recognize') + +if __name__ == '__main__': + app.run(debug=True, host="0.0.0.0", port=5005) diff --git a/app4.py b/app4.py new file mode 100644 index 0000000..164e767 --- /dev/null +++ b/app4.py @@ -0,0 +1,93 @@ +import os +from flask import Flask, request, jsonify +import face_recognition +import pickle +from PIL import Image +import numpy as np + +app = Flask(__name__) + +UPLOAD_FOLDER = 'student_roll/uploads/' +FACE_DATA_FOLDER = 'student_roll/face_data/' + +os.makedirs(UPLOAD_FOLDER, exist_ok=True) +os.makedirs(FACE_DATA_FOLDER, exist_ok=True) + +def convert_image_to_8bit_rgb(image_path): + with Image.open(image_path) as img: + if img.mode != 'RGB': + img = img.convert('RGB') + img = img.convert('RGB') # Ensure conversion to 8-bit per channel + img_array = np.array(img) + return img_array + +@app.route('/upload', methods=['POST']) +def upload_image(): + if 'image' not in request.files: + return jsonify({"error": "No image part in the request"}), 400 + + file = request.files['image'] + if file.filename == '': + return jsonify({"error": "No selected file"}), 400 + + student_roll = request.form.get('student_roll') + if not student_roll: + return jsonify({"error": "Student roll number is required"}), 400 + + file_path = os.path.join(UPLOAD_FOLDER, f"{student_roll}.jpg") + file.save(file_path) + + try: + # Convert image to 8-bit RGB if necessary + image = convert_image_to_8bit_rgb(file_path) + face_encodings = face_recognition.face_encodings(image) + + if not face_encodings: + return jsonify({"error": "No face found in the image"}), 400 + + face_data_path = os.path.join(FACE_DATA_FOLDER, f"{student_roll}.pkl") + with open(face_data_path, 'wb') as f: + pickle.dump(face_encodings[0], f) + + return jsonify({"message": "Image and face data uploaded successfully"}), 200 + except Exception as e: + return jsonify({"error": str(e)}), 500 + +@app.route('/recognize_student', methods=['POST']) +def recognize_student(): + if 'image' not in request.files: + return jsonify({"error": "No image part in the request"}), 400 + + file = request.files['image'] + if file.filename == '': + return jsonify({"error": "No selected file"}), 400 + + file_path = os.path.join(UPLOAD_FOLDER, "temp.jpg") + file.save(file_path) + + try: + # Convert image to 8-bit RGB if necessary + image = convert_image_to_8bit_rgb(file_path) + face_encodings = face_recognition.face_encodings(image) + + if not face_encodings: + return jsonify({"error": "No face found in the image"}), 400 + + uploaded_face_encoding = face_encodings[0] + + # Load all stored face data + for face_data_file in os.listdir(FACE_DATA_FOLDER): + with open(os.path.join(FACE_DATA_FOLDER, face_data_file), 'rb') as f: + known_face_encoding = pickle.load(f) + matches = face_recognition.compare_faces([known_face_encoding], uploaded_face_encoding) + + if matches[0]: + student_roll = os.path.splitext(face_data_file)[0] + return jsonify({"student_roll": student_roll}), 200 + + return jsonify({"error": "No matching student found"}), 404 + except Exception as e: + return jsonify({"error": str(e)}), 500 + +if __name__ == '__main__': + app.run(debug=True, host="0.0.0.0", port=5005) diff --git a/app5.py b/app5.py new file mode 100644 index 0000000..1916ab2 --- /dev/null +++ b/app5.py @@ -0,0 +1,81 @@ +from flask import Flask, request, jsonify +import os +import face_recognition +import pickle +from werkzeug.utils import secure_filename + +app = Flask(__name__) +app.config['UPLOAD_FOLDER'] = 'uploads/' +app.config['STUDENT_DATA_FILE'] = 'students_data.pkl' + +if not os.path.exists(app.config['UPLOAD_FOLDER']): + os.makedirs(app.config['UPLOAD_FOLDER']) + +# Load or initialize student data +if os.path.exists(app.config['STUDENT_DATA_FILE']): + with open(app.config['STUDENT_DATA_FILE'], 'rb') as f: + students_db = pickle.load(f) +else: + students_db = {} + +def save_student_data(): + with open(app.config['STUDENT_DATA_FILE'], 'wb') as f: + pickle.dump(students_db, f) + +@app.route('/upload', methods=['POST']) +def upload_image(): + if 'image' not in request.files or 'student_id' not in request.form: + return jsonify({'error': 'Image or student_id not provided'}), 400 + + image = request.files['image'] + student_id = request.form['student_id'] + filename = secure_filename(f"{student_id}_{image.filename}") + filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) + image.save(filepath) + + # Load the image file into a numpy array + image = face_recognition.load_image_file(filepath) + # Get the face encoding for the image + face_encodings = face_recognition.face_encodings(image) + + if len(face_encodings) > 0: + # Assuming the first face found in the image is the correct one + students_db[student_id] = face_encodings[0] + save_student_data() + return jsonify({'message': 'Image uploaded and student registered successfully', 'student_id': student_id}), 200 + else: + return jsonify({'error': 'No faces found in the image'}), 400 + +@app.route('/recognize_image', methods=['POST']) +def recognize_image(): + if 'image' not in request.files: + return jsonify({'error': 'Image not provided'}), 400 + + image = request.files['image'] + # Load the uploaded image file into a numpy array + unknown_image = face_recognition.load_image_file(image) + # Get the face encodings for the uploaded image + unknown_encodings = face_recognition.face_encodings(unknown_image) + + if len(unknown_encodings) > 0: + unknown_encoding = unknown_encodings[0] + best_match_id = None + best_match_score = None + + for student_id, known_encoding in students_db.items(): + # Calculate the distance between the known encoding and the uploaded image encoding + distance = face_recognition.face_distance([known_encoding], unknown_encoding)[0] + # Convert distance to accuracy score (the closer the distance, the higher the accuracy) + accuracy_score = (1 - distance) * 100 + + if best_match_score is None or accuracy_score > best_match_score: + best_match_id = student_id + best_match_score = accuracy_score + + if best_match_id: + return jsonify({'student_id': best_match_id, 'accuracy_score': best_match_score}), 200 + + return jsonify({'error': 'Student not recognized'}), 404 + +if __name__ == '__main__': + app.run(debug=True, host="0.0.0.0", port=5005) diff --git a/app6.py b/app6.py new file mode 100644 index 0000000..c844647 --- /dev/null +++ b/app6.py @@ -0,0 +1,86 @@ +from flask import Flask, request, jsonify +import os +import face_recognition +import pickle +from werkzeug.utils import secure_filename +from time import time + +app = Flask(__name__) +app.config['UPLOAD_FOLDER'] = 'uploads/' +app.config['STUDENT_DATA_FILE'] = 'students_data.pkl' + +if not os.path.exists(app.config['UPLOAD_FOLDER']): + os.makedirs(app.config['UPLOAD_FOLDER']) + +# Load or initialize student data +if os.path.exists(app.config['STUDENT_DATA_FILE']): + with open(app.config['STUDENT_DATA_FILE'], 'rb') as f: + students_db = pickle.load(f) +else: + students_db = {} + +def save_student_data(): + with open(app.config['STUDENT_DATA_FILE'], 'wb') as f: + pickle.dump(students_db, f) + +@app.route('/upl', methods=['POST']) +def upload_image(): + if 'face' not in request.files or 'student_id' not in request.form: + return jsonify({'error': 'Image or student_id not provided'}), 400 + + image = request.files['face'] + student_id = request.form['student_id'] + timestamp = int(time()) + filename = secure_filename(f"{timestamp}.jpg") + student_folder = os.path.join(app.config['UPLOAD_FOLDER'], student_id) + if not os.path.exists(student_folder): + os.makedirs(student_folder) + filepath = os.path.join(student_folder, filename) + image.save(filepath) + + # Load the image file into a numpy array + image_array = face_recognition.load_image_file(filepath) + # Get the face encoding for the image + face_encodings = face_recognition.face_encodings(image_array) + + if len(face_encodings) > 0: + # Assuming the first face found in the image is the correct one + students_db[student_id] = face_encodings[0] + save_student_data() + return jsonify({'message': 'Image uploaded and student registered successfully', 'student_id': student_id}), 200 + else: + return jsonify({'error': 'No faces found in the image'}), 400 + +@app.route('/rec', methods=['POST']) +def recognize_image(): + if 'image' not in request.files: + return jsonify({'error': 'Image not provided'}), 400 + + image = request.files['image'] + # Load the uploaded image file into a numpy array + unknown_image = face_recognition.load_image_file(image) + # Get the face encodings for the uploaded image + unknown_encodings = face_recognition.face_encodings(unknown_image) + + if len(unknown_encodings) > 0: + unknown_encoding = unknown_encodings[0] + best_match_id = None + best_match_score = None + + for student_id, known_encoding in students_db.items(): + # Calculate the distance between the known encoding and the uploaded image encoding + distance = face_recognition.face_distance([known_encoding], unknown_encoding)[0] + # Convert distance to accuracy score (the closer the distance, the higher the accuracy) + accuracy_score = (1 - distance) * 100 + + if best_match_score is None or accuracy_score > best_match_score: + best_match_id = student_id + best_match_score = accuracy_score + + if best_match_id: + return jsonify({'student_id': best_match_id, 'accuracy_score': best_match_score}), 200 + + return jsonify({'error': 'Student not recognized'}), 404 + +if __name__ == '__main__': + app.run(debug=True, host="0.0.0.0", port=5005) diff --git a/bin/Activate.ps1 b/bin/Activate.ps1 new file mode 100644 index 0000000..b49d77b --- /dev/null +++ b/bin/Activate.ps1 @@ -0,0 +1,247 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/bin/activate b/bin/activate new file mode 100755 index 0000000..f26bdfb --- /dev/null +++ b/bin/activate @@ -0,0 +1,69 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null + fi + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="/data/p/p/kar/python_attendance_image" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1="(python_attendance_image) ${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT="(python_attendance_image) " + export VIRTUAL_ENV_PROMPT +fi + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null +fi diff --git a/bin/activate.csh b/bin/activate.csh new file mode 100755 index 0000000..d6c792c --- /dev/null +++ b/bin/activate.csh @@ -0,0 +1,26 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/data/p/p/kar/python_attendance_image" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = "(python_attendance_image) $prompt" + setenv VIRTUAL_ENV_PROMPT "(python_attendance_image) " +endif + +alias pydoc python -m pydoc + +rehash diff --git a/bin/activate.fish b/bin/activate.fish new file mode 100644 index 0000000..4b0c99d --- /dev/null +++ b/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/); you cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + set -e _OLD_FISH_PROMPT_OVERRIDE + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + end + + set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV "/data/p/p/kar/python_attendance_image" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# Unset PYTHONHOME if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # Save the current fish_prompt function as the function _old_fish_prompt. + functions -c fish_prompt _old_fish_prompt + + # With the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command. + set -l old_status $status + + # Output the venv prompt; color taken from the blue of the Python logo. + printf "%s%s%s" (set_color 4B8BBE) "(python_attendance_image) " (set_color normal) + + # Restore the return status of the previous command. + echo "exit $old_status" | . + # Output the original/"old" prompt. + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" + set -gx VIRTUAL_ENV_PROMPT "(python_attendance_image) " +end diff --git a/bin/f2py b/bin/f2py new file mode 100755 index 0000000..4bdddc3 --- /dev/null +++ b/bin/f2py @@ -0,0 +1,8 @@ +#!/data/p/p/kar/python_attendance_image/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from numpy.f2py.f2py2e import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/bin/face_detection b/bin/face_detection new file mode 100755 index 0000000..961f3c0 --- /dev/null +++ b/bin/face_detection @@ -0,0 +1,8 @@ +#!/data/p/p/kar/python_attendance_image/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from face_recognition.face_detection_cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/bin/face_recognition b/bin/face_recognition new file mode 100755 index 0000000..bb7c28e --- /dev/null +++ b/bin/face_recognition @@ -0,0 +1,8 @@ +#!/data/p/p/kar/python_attendance_image/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from face_recognition.face_recognition_cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/bin/flask b/bin/flask new file mode 100755 index 0000000..573c687 --- /dev/null +++ b/bin/flask @@ -0,0 +1,8 @@ +#!/data/p/p/kar/python_attendance_image/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from flask.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/bin/pip b/bin/pip new file mode 100755 index 0000000..200f5d6 --- /dev/null +++ b/bin/pip @@ -0,0 +1,8 @@ +#!/data/p/p/kar/python_attendance_image/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/bin/pip3 b/bin/pip3 new file mode 100755 index 0000000..200f5d6 --- /dev/null +++ b/bin/pip3 @@ -0,0 +1,8 @@ +#!/data/p/p/kar/python_attendance_image/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/bin/pip3.10 b/bin/pip3.10 new file mode 100755 index 0000000..200f5d6 --- /dev/null +++ b/bin/pip3.10 @@ -0,0 +1,8 @@ +#!/data/p/p/kar/python_attendance_image/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/bin/python b/bin/python new file mode 120000 index 0000000..acd4152 --- /dev/null +++ b/bin/python @@ -0,0 +1 @@ +/usr/bin/python \ No newline at end of file diff --git a/bin/python3 b/bin/python3 new file mode 120000 index 0000000..d8654aa --- /dev/null +++ b/bin/python3 @@ -0,0 +1 @@ +python \ No newline at end of file diff --git a/bin/python3.10 b/bin/python3.10 new file mode 120000 index 0000000..d8654aa --- /dev/null +++ b/bin/python3.10 @@ -0,0 +1 @@ +python \ No newline at end of file diff --git a/pyvenv.cfg b/pyvenv.cfg new file mode 100644 index 0000000..0537ffc --- /dev/null +++ b/pyvenv.cfg @@ -0,0 +1,3 @@ +home = /usr/bin +include-system-site-packages = false +version = 3.10.12 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..56014ac --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +flask-3.0.3 +Flask_Cors-4.0.1 +face_recognition-1.3.0 +numpy-1.26.4 +pickle5 diff --git a/student_encodings.pkl b/student_encodings.pkl new file mode 100644 index 0000000000000000000000000000000000000000..cbc3e9bb5fc0725e0b6c2c86c4d6b55baf75df95 GIT binary patch literal 1183 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 YXX@p9ItAxlzry`${H + + + Upload Student Image + + +

Upload Student Image

+
+ + +

+ + +

+ +
+ + diff --git a/upload.py b/upload.py new file mode 100644 index 0000000..f0893b8 --- /dev/null +++ b/upload.py @@ -0,0 +1,29 @@ +from flask import Flask, render_template, request, jsonify, make_response +import os + +app = Flask(__name__) +UPLOAD_FOLDER = 'uploads' +app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER + +@app.route('/') +def upload_form(): + return render_template('upload.html') + +@app.route('/upload', methods=['POST']) +def upload_file(): + folder_number = request.form['roll_number'] + images = request.files.getlist('images[]') + + folder_path = os.path.join(app.config['UPLOAD_FOLDER'], folder_number) + os.makedirs(folder_path, exist_ok=True) + + for image in images: + if image.filename == '': + continue + filename = image.filename + image.save(os.path.join(folder_path, filename)) + + return make_response(jsonify('success'), 200) + +if __name__ == '__main__': + app.run(debug=True, host="0.0.0.0", port=5005) diff --git a/uploads/1111111111/1719166994.jpg b/uploads/1111111111/1719166994.jpg new file mode 100644 index 0000000000000000000000000000000000000000..62b06df06ea778d12a5733b5a78b0b7cad84e84c GIT binary patch literal 10048 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 literal 0 HcmV?d00001 diff --git a/uploads/3333/1719166349.jpg b/uploads/3333/1719166349.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9b8db7cc497732fadfc7be0b59b27828e6c18066 GIT binary patch literal 8672 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 SthrF&OaMAA6m&x#R{jgQjO#Q2 literal 0 HcmV?d00001