yolov5face - veka-server/onnx-php GitHub Wiki
yolov5face
model sources : https://github.com/FaceONNX/FaceONNX.Models (yolov5s-face.onnx)
require_once(__DIR__.'/../vendor/autoload.php');
Onnx\Library::setFolder(__DIR__.'/../');
Onnx\Library::install();
$ia = new class extends \Onnx\Task\Vision {
protected array $tags = [];
protected $rescale_factor = 0.00392156862745098 ;
protected $format = 'rgb';
protected $height = 640;
protected $width = 640;
protected $shape = 'bchw'; /* batch channel height width */
protected mixed $modelNameOrPath = __DIR__.'/../models/faceonnx/yolov5s-face.onnx';
protected function postprocess($result) {
$out = $result[$this->model->outputs()[0]['name']][0]; // Suppression de la première dimension
$faces = [];
foreach ($out as $face) {
// Extraire les informations de la boîte de délimitation
$boundingBox = [
'x1' => $face[0],
'y1' => $face[1],
'w' => $face[2],
'h' => $face[3],
'x2' => $face[0] + $face[2],
'y2' => $face[1] + $face[3]
];
// Extraire le score de confiance
$confidenceScore = $face[4];
if($confidenceScore <= 0.5)
continue;
// Extraire les points de repère
$landmarks = [];
for ($i = 5; $i < 15; $i += 2) {
$landmarks[] = [
'x' => $face[$i],
'y' => $face[$i + 1]
];
}
// Ajouter les informations du visage au tableau des résultats
$faces[] = [
'boundingBox' => $boundingBox,
'confidenceScore' => $confidenceScore,
'landmarks' => $landmarks
];
}
$filteredResults = $this->nonMaxSuppression($faces, 0.5); // Par exemple, seuil IoU de 0.5
return $filteredResults;
}
// Fonction pour calculer l'IoU
function calculateIoU($boxA, $boxB) {
// Assurez-vous que les coordonnées sont correctes
if ($boxA['x1'] >= $boxA['x2'] || $boxA['y1'] >= $boxA['y2'] || $boxB['x1'] >= $boxB['x2'] || $boxB['y1'] >= $boxB['y2']) {
return 0.0; // Retourne 0 si les boîtes ne sont pas valides
}
// Calculer les coordonnées de l'intersection
$xA = max($boxA['x1'], $boxB['x1']);
$yA = max($boxA['y1'], $boxB['y1']);
$xB = min($boxA['x2'], $boxB['x2']);
$yB = min($boxA['y2'], $boxB['y2']);
// Calculer l'aire de l'intersection
$intersectionWidth = max(0, $xB - $xA);
$intersectionHeight = max(0, $yB - $yA);
$intersectionArea = $intersectionWidth * $intersectionHeight;
// Calculer l'aire des deux boîtes de délimitation
$boxAArea = ($boxA['x2'] - $boxA['x1']) * ($boxA['y2'] - $boxA['y1']);
$boxBArea = ($boxB['x2'] - $boxB['x1']) * ($boxB['y2'] - $boxB['y1']);
// Calculer l'IoU
$unionArea = $boxAArea + $boxBArea - $intersectionArea;
if ($unionArea == 0) {
return 0.0; // Eviter la division par zéro
}
$iou = $intersectionArea / $unionArea;
return $iou;
}
// Fonction de suppression non maximale
function nonMaxSuppression($faces, $iouThreshold) {
usort($faces, function ($a, $b) {
return $b['confidenceScore'] <=> $a['confidenceScore'];
});
$suppressed = [];
$keep = [];
foreach ($faces as $i => $faceA) {
if (isset($suppressed[$i])) {
continue;
}
$keep[] = $faceA;
foreach ($faces as $j => $faceB) {
if ($i === $j) {
continue;
}
if ($this->calculateIoU($faceA['boundingBox'], $faceB['boundingBox']) > $iouThreshold) {
$suppressed[$j] = true;
}
}
}
return $keep;
}
};
$ia->loadModel();
$tags = $ia->getTags( __DIR__ . '\images\sexy.jpg');
var_dump($tags);