From c428f394561c80de4156a35eb04cf75620800b95 Mon Sep 17 00:00:00 2001 From: Arnaud Robin Date: Sun, 30 Mar 2025 04:33:05 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(frontend)=20add=20thug=20glasses?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added functionality to draw glasses on detected faces by calculating eye positions and scaling the glasses image accordingly. Initialized glasses image in the constructor for improved visual effects during face tracking. --- src/frontend/public/assets/glasses.png | Bin 0 -> 457 bytes .../components/blur/FaceLandmarksProcessor.ts | 63 +++++++++++++++--- 2 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 src/frontend/public/assets/glasses.png diff --git a/src/frontend/public/assets/glasses.png b/src/frontend/public/assets/glasses.png new file mode 100644 index 0000000000000000000000000000000000000000..a0afd63a1488132fbf552a8cb9b34e5d300ae647 GIT binary patch literal 457 zcmeAS@N?(olHy`uVBq!ia0y~yU|z()z!bs63>0B~vH3obVo7)Ob!1@J*w6hZkrl{i zEDmyaVpw-h<|UBB8Q>G*>R#XjWd8sEU+k)WBS=L_kY6x^!?PP{Kz5*~i(^Q|t+#hJ z@*Ys&adn)Qa?;0hvY4iXwbP4r-d`(Cxz;iQ^^gYKUri5O6|ypDsn=AkP^^qgYc4%E z{e3U?-O*;8Y9QLBbl2+rt1;edDe?bt7(OF`%Cox>Yxjb#7; literal 0 HcmV?d00001 diff --git a/src/frontend/src/features/rooms/livekit/components/blur/FaceLandmarksProcessor.ts b/src/frontend/src/features/rooms/livekit/components/blur/FaceLandmarksProcessor.ts index da368f70..6661c487 100644 --- a/src/frontend/src/features/rooms/livekit/components/blur/FaceLandmarksProcessor.ts +++ b/src/frontend/src/features/rooms/livekit/components/blur/FaceLandmarksProcessor.ts @@ -46,10 +46,20 @@ export class FaceLandmarksProcessor implements BackgroundProcessorInterface { type: ProcessorType + // Glasses image element + glassesImage?: HTMLImageElement + constructor(opts: BackgroundOptions) { this.name = 'face_landmarks' this.options = opts this.type = ProcessorType.FACE_LANDMARKS + this._initGlassesImage() + } + + private _initGlassesImage() { + this.glassesImage = new Image() + this.glassesImage.src = '/assets/glasses.png' // You'll need to add this image to your public assets + this.glassesImage.crossOrigin = 'anonymous' } static get isSupported() { @@ -170,19 +180,54 @@ export class FaceLandmarksProcessor implements BackgroundProcessorInterface { return } - // Draw face landmarks + // Draw face landmarks (optional, for debugging) this.outputCanvasCtx!.strokeStyle = '#00FF00' this.outputCanvasCtx!.lineWidth = 2 for (const face of this.faceLandmarkerResult.faceLandmarks) { - for (const landmark of face) { - // Use the same dimensions as the canvas/video display size - const x = landmark.x * PROCESSING_WIDTH - const y = landmark.y * PROCESSING_HEIGHT - - this.outputCanvasCtx!.beginPath() - this.outputCanvasCtx!.arc(x, y, 2, 0, 2 * Math.PI) - this.outputCanvasCtx!.stroke() + // Find eye landmarks (indices 33 and 263 are the left and right eye centers) + const leftEye = face[33] + const rightEye = face[263] + + if (leftEye && rightEye) { + // Calculate glasses position and size + const eyeDistance = Math.sqrt( + Math.pow(rightEye.x - leftEye.x, 2) + + Math.pow(rightEye.y - leftEye.y, 2) + ) + + // Scale glasses based on eye distance + const glassesWidth = eyeDistance * PROCESSING_WIDTH * 2.5 // Adjust multiplier as needed + const glassesHeight = glassesWidth * 0.7 // Adjust aspect ratio as needed + + // Calculate center position between eyes + const centerX = (leftEye.x + rightEye.x) / 2 + const centerY = (leftEye.y + rightEye.y) / 2 + + // Draw glasses + this.outputCanvasCtx!.save() + this.outputCanvasCtx!.translate( + centerX * PROCESSING_WIDTH, + centerY * PROCESSING_HEIGHT + ) + + // Calculate rotation angle based on eye positions + const angle = Math.atan2( + rightEye.y - leftEye.y, + rightEye.x - leftEye.x + ) + this.outputCanvasCtx!.rotate(angle) + + // Draw glasses centered at the midpoint between eyes + this.outputCanvasCtx!.drawImage( + this.glassesImage!, + -glassesWidth / 2, + -glassesHeight / 2, + glassesWidth, + glassesHeight + ) + + this.outputCanvasCtx!.restore() } } }