import styles from './Object_Detection.module.css'; import { useRef, useEffect, useState } from 'react' const FRAME_QUALITY = 0.7; const FRAMES_PER_SECOND = 5; function Object_Detection() { const videoRef = useRef(null); const canvasRefBBox = useRef(null); const canvasRefSending = useRef(null); const ctxRefBBox = useRef(null); const ctxRefSending = useRef(null); const [error, setError] = useState(false); const socketRef = useRef(null); const [running, setRunning] = useState(false); const streamRef = useRef(null); const sendImageIntervall = useRef(null); useEffect(() => { if (canvasRefBBox.current) { ctxRefBBox.current = canvasRefBBox.current.getContext("2d"); printDefault(); } if (canvasRefSending.current) { ctxRefSending.current = canvasRefSending.current.getContext("2d"); } }, []); const drawBBox = (bboxes) => { const canvas = canvasRefBBox.current; if (!canvas) return; const ctx = ctxRefBBox.current; if (!ctx) return; ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.strokeStyle = "red"; ctx.lineWidth = 1; if (bboxes) { bboxes.forEach(edge => { const x1 = Math.max(edge[0], 0); const y1 = Math.max(edge[1], 0); const x2 = Math.min(edge[2], canvas.width); const y2 = Math.min(edge[3], canvas.height); ctx.strokeRect(x1, y1, x2 - x1, y2 - y1); }); } }; const sendImage = () => { const video = videoRef.current; const canvas = canvasRefSending.current; const ctx = ctxRefSending.current; if (!ctx) return; if (!canvas) return; if (!video) return; ctx.drawImage(video, 0, 0, canvas.width, canvas.height); canvas.toBlob(async (blob) => { if (!blob) return; try { socketRef.current?.send(blob) } catch (e) { setError(true); } }, "image/jpeg", FRAME_QUALITY); }; const printDefault = () => { const canvas = canvasRefBBox.current; const ctx = ctxRefBBox.current; if (!ctx) return; if (!canvas) return; const img = new Image(); img.src = "/yolo.jfif"; const canvasW = canvas.width; const canvasH = canvas.height; img.onload = () => { ctx.drawImage(img, 0, 0, canvas.width, canvas.height); }; } const startRecording = async () => { if (running) { printDefault(); setRunning(false); endWebcam(); return; } try { const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: false, }); streamRef.current = stream; if (videoRef.current) { videoRef.current.srcObject = stream; } } catch (err) { console.error("Error accessing webcam:", err); } const socket = new WebSocket("wss://api.marvinkrausser.com/predict_face"); socketRef.current = socket; socket.onopen = () => { console.log("Connected"); const canvas = canvasRefBBox.current; const ctx = ctxRefBBox.current; if (!ctx) return; if (!canvas) return; ctx.clearRect(0, 0, canvas.width, canvas.height); sendImageIntervall.current = setInterval(sendImage, 1000 / FRAMES_PER_SECOND); } socket.onmessage = (event) => { drawBBox(JSON.parse(event.data).bboxes); } socket.onerror = () => { console.log("Websocket Error"); printDefault(); setRunning(false); endWebcam(); } socket.onclose = () => { console.log("Disconnected"); printDefault(); setRunning(false); endWebcam(); } setRunning(true); } useEffect(() => { return () => { endWebcam(); }; }, []); const endWebcam = () => { if (socketRef.current) { socketRef.current.close(); socketRef.current = null; } if (videoRef.current) { videoRef.current.srcObject = null; } if (streamRef.current) { streamRef.current.getTracks().forEach(track => track.stop()); } if(sendImageIntervall.current){ clearInterval(sendImageIntervall.current); } } return (

Face Detection

The model's performance has been limited to 5 FPS due to low-end server hardware constraints.

The webcam video is transmitted to a server for processing. The server does not store, train on, or use the data for any purpose other than face detection.

This Project is an implementation of the YOLO (You Only Look Once) algorithm. It was implemented with Pytorch and trained on a Dataset from Roboflow.

) } export default Object_Detection;