nudenet‐detection - veka-server/onnx-php GitHub Wiki
nudenet-detection
model sources : https://github.com/notAI-tech/NudeNet (v3.4 : 640m.onnx)
require_once(__DIR__.'/../vendor/autoload.php');
Onnx\Library::setFolder(__DIR__.'/../');
Onnx\Library::install();
$ia = new class extends \Onnx\Task\Vision {
protected array $tags = [
"FEMALE_GENITALIA_COVERED",
"FACE_FEMALE",
"BUTTOCKS_EXPOSED",
"FEMALE_BREAST_EXPOSED",
"FEMALE_GENITALIA_EXPOSED",
"MALE_BREAST_EXPOSED",
"ANUS_EXPOSED",
"FEET_EXPOSED",
"BELLY_COVERED",
"FEET_COVERED",
"ARMPITS_COVERED",
"ARMPITS_EXPOSED",
"FACE_MALE",
"BELLY_EXPOSED",
"MALE_GENITALIA_EXPOSED",
"ANUS_COVERED",
"FEMALE_BREAST_COVERED",
"BUTTOCKS_COVERED",
];
protected $rescale_factor = 1/255 ;
protected $format = 'rgb';
protected $height = 320;
protected $width = 320;
protected $shape = 'bchw'; /* batch channel height width */
protected mixed $modelNameOrPath = __DIR__.'/../models/640m.onnx' ;
protected function postprocess($result) {
$resize_factor = 1;
$pad_left = 0;
$pad_top = 0;
// Supposons que $output est une matrice multidimensionnelle.
$output_squeezed = array_map('array_values', $result[$this->model->outputs()[0]['name']]->toArray()[0]);
$output_transposed = array_map(null, ...$output_squeezed);
$rows = count($output_transposed);
$boxes = array();
$scores = array();
$class_ids = array();
for ($i = 0; $i < $rows; $i++) {
// Extraction des scores de classes à partir de l'indice 4
$classes_scores = array_slice($output_transposed[$i], 4);
$max_score = max($classes_scores);
if ($max_score >= 0.2) {
$class_id = array_search($max_score, $classes_scores);
$x = $output_transposed[$i][0];
$y = $output_transposed[$i][1];
$w = $output_transposed[$i][2];
$h = $output_transposed[$i][3];
$left = intval(round(($x - $w * 0.5 - $pad_left) * $resize_factor));
$top = intval(round(($y - $h * 0.5 - $pad_top) * $resize_factor));
$width = intval(round($w * $resize_factor));
$height = intval(round($h * $resize_factor));
$class_ids[] = $class_id;
$scores[] = $max_score;
// $boxes[] = array($left, $top, $width, $height);
/** hack test */
$boxes[] = array($x - $w * 0.5, $y - $h * 0.5 , $w, $h);
}
}
// Utilisation de Non-Maximum Suppression (NMS)
$indices = $this->nmsBoxes($boxes, $scores, 0.25, 0.45);
$detections = array();
foreach ($indices as $i) {
$box = $boxes[$i];
$score = $scores[$i];
$class_id = $class_ids[$i];
$detections[] = array(
"class" => $this->tags[$class_id],
"score" => floatval($score),
"box" => $box
);
}
return $detections;
}
function nmsBoxes($boxes, $scores, $scoreThreshold, $nmsThreshold) {
$selectedIndices = [];
// Filtrer les boîtes et les scores en fonction du seuil de score
$filteredIndices = array_filter(array_keys($scores), function($i) use ($scores, $scoreThreshold) {
return $scores[$i] >= $scoreThreshold;
});
// Tri des indices filtrés en fonction des scores décroissants
usort($filteredIndices, function($a, $b) use ($scores) {
return $scores[$b] <=> $scores[$a];
});
while (!empty($filteredIndices)) {
$current = array_shift($filteredIndices);
$selectedIndices[] = $current;
$filteredIndices = array_filter($filteredIndices, function($i) use ($boxes, $nmsThreshold, $current) {
$iou = $this->calculateIOU($boxes[$current], $boxes[$i]);
return $iou < $nmsThreshold;
});
}
return $selectedIndices;
}
function calculateIOU($boxA, $boxB) {
// Coordonnées de la boîte A : [x, y, largeur, hauteur]
$xA = $boxA[0];
$yA = $boxA[1];
$wA = $boxA[2];
$hA = $boxA[3];
// Coordonnées de la boîte B : [x, y, largeur, hauteur]
$xB = $boxB[0];
$yB = $boxB[1];
$wB = $boxB[2];
$hB = $boxB[3];
// Calcul des coordonnées du rectangle d'intersection
$x1 = max($xA, $xB);
$y1 = max($yA, $yB);
$x2 = min($xA + $wA, $xB + $wB);
$y2 = min($yA + $hA, $yB + $hB);
// Calcul de l'aire de l'intersection
$intersectionArea = max(0, $x2 - $x1 + 1) * max(0, $y2 - $y1 + 1);
// Calcul de l'aire des boîtes A et B
$boxAArea = ($wA + 1) * ($hA + 1);
$boxBArea = ($wB + 1) * ($hB + 1);
// Calcul de l'Union
$unionArea = $boxAArea + $boxBArea - $intersectionArea;
// Calcul de l'IOU
if ($unionArea > 0) {
$iou = $intersectionArea / $unionArea;
} else {
$iou = 0.0;
}
return $iou;
}
};
$ia->loadModel();
$tags = $ia->getTags( __DIR__ . '\images\sexy.jpg');
var_dump($tags);