pa tulong naman po sa face detection using face api , javascript and php . nadedect naman ang faces na nakastore sa database with the employee no pero hindi nagpupush ang attendance
const faceMatcherThreshold = 0.5; // Lowered threshold for better matching
let labels = [];
let detectedFaces = [];
let sendingData = false;
function loadEmployeeDataAndFaceModels() {
fetch("get_faces.php")
.then((response) => response.json())
.then((data) => {
if (data.status === "success") {
labels = data.data.map((employee) => ({
label: employee.employee_no,
name: employee.name,
facePath: employee.face_path,
}));
console.log("Employee data loaded successfully:", labels);
loadFaceRecognitionModels();
} else {
console.error("Error fetching employee data:", data.message);
alert("Failed to fetch employee data.");
}
})
.catch((error) => {
console.error("Error loading employee data:", error);
});
}
function loadFaceRecognitionModels() {
Promise.all([
faceapi.nets.ssdMobilenetv1.loadFromUri("models"),
faceapi.nets.faceRecognitionNet.loadFromUri("models"),
faceapi.nets.faceLandmark68Net.loadFromUri("models"),
])
.then(() => {
console.log("Models loaded successfully");
startFaceDetection();
})
.catch((err) => {
console.error("Error loading face-api.js models:", err);
alert("Error loading face recognition models. Please try again.");
});
}
async function getLabeledFaceDescriptions() {
const labeledDescriptors = [];
console.log("Fetching labeled face descriptors");
for (const employee of labels) {
const descriptions = [];
const imagePaths = employee.facePath.split(","); // Split the paths by commas
// Iterate over each image path for the employee
for (const imgPath of imagePaths) {
try {
const trimmedPath = imgPath.trim(); // Trim any extra spaces from the image path
const img = await faceapi.fetchImage(trimmedPath); // Fetch the image
const detections = await faceapi
.detectSingleFace(img)
.withFaceLandmarks()
.withFaceDescriptor();
if (detections) {
descriptions.push(detections.descriptor);
console.log("Face detected:", detections);
} else {
console.log(
}
} catch (error) {
console.error(
}
}
if (descriptions.length > 0) {
detectedFaces.push(employee);
labeledDescriptors.push(new faceapi.LabeledFaceDescriptors(employee.label, descriptions));
}
}
return labeledDescriptors;
}
async function startFaceDetection() {
const video = document.getElementById("preview");
const canvas = document.getElementById("overlay");
// Wait for the video to be ready
video.addEventListener("loadeddata", async () => {
console.log("Video is ready, starting face detection");
// Set canvas size to match video dimensions
const displaySize = { width: video.width, height: video.height };
faceapi.matchDimensions(canvas, displaySize);
// Load labeled face descriptions
const labeledFaceDescriptors = await getLabeledFaceDescriptions();
console.log("Employee data loaded successfully:", labeledFaceDescriptors);
const faceMatcher = new faceapi.FaceMatcher(labeledFaceDescriptors, faceMatcherThreshold);
video.addEventListener("play", () => {
const interval = setInterval(async () => {
// Detect faces in the video
const detections = await faceapi
.detectAllFaces(video)
.withFaceLandmarks()
.withFaceDescriptors();
console.log("Detected faces:", detections);
const resizedDetections = faceapi.resizeResults(detections, displaySize);
canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
const results = resizedDetections.map((detection) => {
const match = faceMatcher.findBestMatch(detection.descriptor);
console.log("Matched face:", match.toString());
return match;
});
// Process only recognized faces
results.forEach((result) => {
if (result.employee !== "unknown") {
console.log("Recognized employee:", result.employee);
markAttendance(result.employee); // Pass the recognized label (employee_no)
}
});
// Draw the bounding boxes
results.forEach((result, i) => {
const box = resizedDetections.detection.box;
const drawBox = new faceapi.draw.DrawBox(box, {
employee: result.toString(),
});
drawBox.draw(canvas);
});
}, 100); // Use 100ms interval for detection
video.addEventListener("pause", () => clearInterval(interval));
});
});
}
async function markAttendance(employee_no) {
if (sendingData) return; // Prevent sending data if already sending
sendingData = true;
const attendanceData = [{
employee_no: employee_no,
time_in: new Date().toLocaleTimeString(),
status: "present",
}];
console.log("Attendance Data being sent:", attendanceData);
try {
const response = await fetch("save_attendance.php", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(attendanceData),
});
const result = await response.json();
console.log("Response from server:", result);
if (result.status === "success") {
console.log("Attendance successfully recorded.");
} else {
console.error("Error recording attendance:", result.message);
}
} catch (error) {
console.error("Error sending attendance data:", error);
} finally {
sendingData = false;
}
}
// Initialize the process when the page loads
document.addEventListener("DOMContentLoaded", () => {
loadEmployeeDataAndFaceModels();
}); get_faces.php
include 'conn.php';
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization");
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('log_errors', 1);
ini_set('error_log', 'php_errors.log');
try {
// Query to fetch employee data
$query = "SELECT
$result = $conn->query($query);
if ($result) {
$data = [];
while ($row = $result->fetch_assoc()) {
$facePaths = $row['face_path'];
$baseUrl = 'You do not have permission to view the full content of this post. Log in or register now.
$facePathArray = explode(',', $facePaths);
$fullFacePaths = array_map(function($path) use ($baseUrl) {
$trimmedPath = trim($path);
if (strpos($trimmedPath, 'http') === false) {
return $baseUrl . ltrim($trimmedPath, '.');
}
return $trimmedPath;
}, $facePathArray);
$data[] = [
"employee_no" => $row['employee_no'],
"name" => $row['first_name'] . ' ' . $row['last_name'],
"face_path" => implode(',', $fullFacePaths)
];
}
echo json_encode(["status" => "success", "data" => $data]);
} else {
echo json_encode(["status" => "error", "message" => "Query execution failed: " . $conn->error]);
}
} catch (Exception $e) {
echo json_encode(["status" => "error", "message" => $e->getMessage()]);
}
$conn->close(); save_attendance.php
$attendanceData = json_decode(file_get_contents("php://input"), true);
if ($attendanceData === null) {
echo json_encode([
"status" => "error",
"message" => "No data received or invalid JSON format."
]);
exit;
}
// Check if the data is valid
if (is_array($attendanceData) && count($attendanceData) > 0) {
$stmt = $conn->prepare("INSERT INTO
// Loop through the attendance data and insert each record
foreach ($attendanceData as $attendance) {
// Prepare and bind parameters
$employee_no = $attendance['employee_no'];
$time_in = $attendance['time_in'];
$status = $attendance['status'];
$stmt->bind_param("sss", $employee_no, $time_in, $status);
// Execute the query to insert the data
if (!$stmt->execute()) {
echo json_encode([
"status" => "error",
"message" => "Error inserting attendance for employee ID: " . $employee_no
]);
exit;
}
}
// Close the statement and connection
$stmt->close();
$conn->close();
// Return success message
echo json_encode([
"status" => "success",
"message" => "Attendance recorded successfully."
]);
} else {
echo json_encode([
"status" => "error",
"message" => "Invalid data."
]);
}
const faceMatcherThreshold = 0.5; // Lowered threshold for better matching
let labels = [];
let detectedFaces = [];
let sendingData = false;
function loadEmployeeDataAndFaceModels() {
fetch("get_faces.php")
.then((response) => response.json())
.then((data) => {
if (data.status === "success") {
labels = data.data.map((employee) => ({
label: employee.employee_no,
name: employee.name,
facePath: employee.face_path,
}));
console.log("Employee data loaded successfully:", labels);
loadFaceRecognitionModels();
} else {
console.error("Error fetching employee data:", data.message);
alert("Failed to fetch employee data.");
}
})
.catch((error) => {
console.error("Error loading employee data:", error);
});
}
function loadFaceRecognitionModels() {
Promise.all([
faceapi.nets.ssdMobilenetv1.loadFromUri("models"),
faceapi.nets.faceRecognitionNet.loadFromUri("models"),
faceapi.nets.faceLandmark68Net.loadFromUri("models"),
])
.then(() => {
console.log("Models loaded successfully");
startFaceDetection();
})
.catch((err) => {
console.error("Error loading face-api.js models:", err);
alert("Error loading face recognition models. Please try again.");
});
}
async function getLabeledFaceDescriptions() {
const labeledDescriptors = [];
console.log("Fetching labeled face descriptors");
for (const employee of labels) {
const descriptions = [];
const imagePaths = employee.facePath.split(","); // Split the paths by commas
// Iterate over each image path for the employee
for (const imgPath of imagePaths) {
try {
const trimmedPath = imgPath.trim(); // Trim any extra spaces from the image path
const img = await faceapi.fetchImage(trimmedPath); // Fetch the image
const detections = await faceapi
.detectSingleFace(img)
.withFaceLandmarks()
.withFaceDescriptor();
if (detections) {
descriptions.push(detections.descriptor);
console.log("Face detected:", detections);
} else {
console.log(
No face detected in ${trimmedPath});}
} catch (error) {
console.error(
Error processing ${imgPath}:, error);}
}
if (descriptions.length > 0) {
detectedFaces.push(employee);
labeledDescriptors.push(new faceapi.LabeledFaceDescriptors(employee.label, descriptions));
}
}
return labeledDescriptors;
}
async function startFaceDetection() {
const video = document.getElementById("preview");
const canvas = document.getElementById("overlay");
// Wait for the video to be ready
video.addEventListener("loadeddata", async () => {
console.log("Video is ready, starting face detection");
// Set canvas size to match video dimensions
const displaySize = { width: video.width, height: video.height };
faceapi.matchDimensions(canvas, displaySize);
// Load labeled face descriptions
const labeledFaceDescriptors = await getLabeledFaceDescriptions();
console.log("Employee data loaded successfully:", labeledFaceDescriptors);
const faceMatcher = new faceapi.FaceMatcher(labeledFaceDescriptors, faceMatcherThreshold);
video.addEventListener("play", () => {
const interval = setInterval(async () => {
// Detect faces in the video
const detections = await faceapi
.detectAllFaces(video)
.withFaceLandmarks()
.withFaceDescriptors();
console.log("Detected faces:", detections);
const resizedDetections = faceapi.resizeResults(detections, displaySize);
canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
const results = resizedDetections.map((detection) => {
const match = faceMatcher.findBestMatch(detection.descriptor);
console.log("Matched face:", match.toString());
return match;
});
// Process only recognized faces
results.forEach((result) => {
if (result.employee !== "unknown") {
console.log("Recognized employee:", result.employee);
markAttendance(result.employee); // Pass the recognized label (employee_no)
}
});
// Draw the bounding boxes
results.forEach((result, i) => {
const box = resizedDetections.detection.box;
const drawBox = new faceapi.draw.DrawBox(box, {
employee: result.toString(),
});
drawBox.draw(canvas);
});
}, 100); // Use 100ms interval for detection
video.addEventListener("pause", () => clearInterval(interval));
});
});
}
async function markAttendance(employee_no) {
if (sendingData) return; // Prevent sending data if already sending
sendingData = true;
const attendanceData = [{
employee_no: employee_no,
time_in: new Date().toLocaleTimeString(),
status: "present",
}];
console.log("Attendance Data being sent:", attendanceData);
try {
const response = await fetch("save_attendance.php", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(attendanceData),
});
const result = await response.json();
console.log("Response from server:", result);
if (result.status === "success") {
console.log("Attendance successfully recorded.");
} else {
console.error("Error recording attendance:", result.message);
}
} catch (error) {
console.error("Error sending attendance data:", error);
} finally {
sendingData = false;
}
}
// Initialize the process when the page loads
document.addEventListener("DOMContentLoaded", () => {
loadEmployeeDataAndFaceModels();
}); get_faces.php
include 'conn.php';
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization");
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('log_errors', 1);
ini_set('error_log', 'php_errors.log');
try {
// Query to fetch employee data
$query = "SELECT
employee_no, first_name, last_name, face_path FROM employee";$result = $conn->query($query);
if ($result) {
$data = [];
while ($row = $result->fetch_assoc()) {
$facePaths = $row['face_path'];
$baseUrl = 'You do not have permission to view the full content of this post. Log in or register now.
$facePathArray = explode(',', $facePaths);
$fullFacePaths = array_map(function($path) use ($baseUrl) {
$trimmedPath = trim($path);
if (strpos($trimmedPath, 'http') === false) {
return $baseUrl . ltrim($trimmedPath, '.');
}
return $trimmedPath;
}, $facePathArray);
$data[] = [
"employee_no" => $row['employee_no'],
"name" => $row['first_name'] . ' ' . $row['last_name'],
"face_path" => implode(',', $fullFacePaths)
];
}
echo json_encode(["status" => "success", "data" => $data]);
} else {
echo json_encode(["status" => "error", "message" => "Query execution failed: " . $conn->error]);
}
} catch (Exception $e) {
echo json_encode(["status" => "error", "message" => $e->getMessage()]);
}
$conn->close(); save_attendance.php
$attendanceData = json_decode(file_get_contents("php://input"), true);
if ($attendanceData === null) {
echo json_encode([
"status" => "error",
"message" => "No data received or invalid JSON format."
]);
exit;
}
// Check if the data is valid
if (is_array($attendanceData) && count($attendanceData) > 0) {
$stmt = $conn->prepare("INSERT INTO
attendance (employee_no, time_in, status) VALUES (?, CURDATE(), ?, ?)");// Loop through the attendance data and insert each record
foreach ($attendanceData as $attendance) {
// Prepare and bind parameters
$employee_no = $attendance['employee_no'];
$time_in = $attendance['time_in'];
$status = $attendance['status'];
$stmt->bind_param("sss", $employee_no, $time_in, $status);
// Execute the query to insert the data
if (!$stmt->execute()) {
echo json_encode([
"status" => "error",
"message" => "Error inserting attendance for employee ID: " . $employee_no
]);
exit;
}
}
// Close the statement and connection
$stmt->close();
$conn->close();
// Return success message
echo json_encode([
"status" => "success",
"message" => "Attendance recorded successfully."
]);
} else {
echo json_encode([
"status" => "error",
"message" => "Invalid data."
]);
}
