facebackend / index.js
alpingo23's picture
Upload index.js
176801f verified
const express = require('express');
const faceapi = require('face-api.js');
const canvas = require('canvas');
const { Canvas, Image, ImageData } = canvas;
const fileUpload = require('express-fileupload');
const path = require('path');
const app = express();
// Enable CORS for all origins
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
app.use(fileUpload());
faceapi.env.monkeyPatch({ Canvas, Image, ImageData });
// Model dosyalarının yolu
// Model files are in root directory on HF Spaces
const MODEL_PATH = __dirname;
// Modelleri yükleme
async function loadModels() {
try {
await Promise.all([
faceapi.nets.ssdMobilenetv1.loadFromDisk(MODEL_PATH),
faceapi.nets.faceLandmark68Net.loadFromDisk(MODEL_PATH),
faceapi.nets.faceRecognitionNet.loadFromDisk(MODEL_PATH),
faceapi.nets.faceExpressionNet.loadFromDisk(MODEL_PATH),
faceapi.nets.ageGenderNet.loadFromDisk(MODEL_PATH),
]);
console.log('Face-api.js models loaded.');
} catch (err) {
console.error('Error loading models:', err);
throw err;
}
}
// Health check endpoint (for Hugging Face Spaces)
app.get('/', (req, res) => {
res.json({
status: 'healthy',
service: 'Face Analysis API',
endpoints: {
predict: '/predict_face (POST)'
},
models: 'face-api.js (SSD MobileNet V1)'
});
});
// Sunucuyu başlatmadan önce modelleri yükle
loadModels().then(() => {
const PORT = process.env.PORT || 5001;
app.listen(PORT, () => {
console.log(`Face analysis server running on port ${PORT}`);
});
}).catch(err => {
console.error('Failed to start server due to model loading error:', err);
});
app.post('/predict_face', async (req, res) => {
if (!req.files || !req.files.image) {
return res.status(400).json({ error: 'No image provided' });
}
const file = req.files.image;
try {
// Görüntüyü canvas'a yükle
const img = await canvas.loadImage(file.data);
const origWidth = img.width;
const origHeight = img.height;
// Görüntüyü analiz et (orijinal boyutlarda)
const detections = await faceapi
.detectAllFaces(img)
.withFaceLandmarks()
.withFaceExpressions()
.withAgeAndGender();
if (detections.length === 0) {
return res.status(400).json({ error: 'No face detected' });
}
// Sonuç objesini oluştur
const result = detections.map(d => {
// Koordinatları orijinal boyutlara göre döndür (face-api.js zaten orijinal boyutları kullanır)
const box = {
x: d.detection.box.x,
y: d.detection.box.y,
width: d.detection.box.width,
height: d.detection.box.height,
};
const landmarks = d.landmarks.positions.map(position => ({
x: position.x,
y: position.y,
}));
return {
age: Math.round(d.age),
gender: d.gender,
genderProbability: d.genderProbability,
expressions: d.expressions,
detection: { box },
landmarks,
imageDimensions: { width: origWidth, height: origHeight }, // Orijinal boyutları ekle
};
});
// Loglama: Backend'den gönderilen boyutları ve koordinatları kontrol et
console.log('Backend Image Dimensions:', result[0].imageDimensions);
console.log('Backend Detection Box:', result[0].detection.box);
console.log('Backend Landmarks Sample:', result[0].landmarks.slice(0, 5)); // İlk 5 landmark
res.json(result[0]); // İlk yüzü döndür
} catch (err) {
console.error('Face analysis error:', err);
res.status(500).json({ error: 'Face analysis failed', details: err.message });
}
});
module.exports = app;