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);