Skip to content

Commit 781a675

Browse files
committed
recognize face by dnn openface
face to vector by dnn openface
1 parent 1ceb6b2 commit 781a675

4 files changed

+158
-5
lines changed

detect_face_by_dnn_ssd.php

-3
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,4 @@
3535
}
3636
}
3737

38-
39-
$data = [];
40-
4138
imwrite("results/_detect_face_by_dnn_ssd.jpg", $src);

face_to_vector_by_dnn_openface.php

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
use CV\Scalar, CV\Size;
4+
use function CV\{imread, imwrite};
5+
6+
$netDet = \CV\DNN\readNetFromCaffe('models/ssd/res10_300x300_ssd_deploy.prototxt', 'models/ssd/res10_300x300_ssd_iter_140000.caffemodel');
7+
$netRecogn = \CV\DNN\readNetFromTorch('models/openface/openface.nn4.small2.v1.t7');
8+
9+
$src = imread("images/faces.jpg");
10+
$size = $src->size(); // 2000x500
11+
12+
$minSide = min($size->width, $size->height);
13+
$divider = $minSide / 300;
14+
\CV\resize($src, $resized, new Size($size->width / $divider, $size->height / $divider)); // 1200x300
15+
16+
//var_export($resized);
17+
18+
$blob = \CV\DNN\blobFromImage($resized, 1, new Size(), new Scalar(104, 177, 123), true, false);
19+
20+
$netDet->setInput($blob);
21+
22+
$r = $netDet->forward();
23+
24+
//var_export($r->shape);
25+
26+
$faces = [];
27+
$scalar = new Scalar(0, 0, 255);
28+
for ($i = 0; $i < $r->shape[2]; $i++) {
29+
$confidence = $r->atIdx([0,0,$i,2]);
30+
if ($confidence > 0.9) {
31+
var_export($confidence);echo "\n";
32+
$startX = $r->atIdx([0,0,$i,3]) * $src->cols;
33+
$startY = $r->atIdx([0,0,$i,4]) * $src->rows;
34+
$endX = $r->atIdx([0,0,$i,5]) * $src->cols;
35+
$endY = $r->atIdx([0,0,$i,6]) * $src->rows;
36+
37+
$face = $src->getImageROI(new \CV\Rect($startX, $startY, $endX - $startX, $endY - $startY));
38+
//imwrite("results/_face.jpg", $face);
39+
40+
$blob = \CV\DNN\blobFromImage($face, 1.0 / 255, new Size(96, 96), new Scalar(), true, false);
41+
$netRecogn->setInput($blob);
42+
$vec = $netRecogn->forward();
43+
44+
//$vec->print();
45+
var_export($vec->data());
46+
}
47+
}

phpdoc.php

+9-2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ public function print() {
5454
return null;
5555
}
5656

57+
/**
58+
* @return array
59+
*/
60+
public function data() {
61+
return [];
62+
}
63+
5764
/**
5865
* @return int
5966
*/
@@ -172,7 +179,7 @@ public function copy_to(Mat $mat, Mat $to = null) {
172179
* @param null $value
173180
* @return int|null
174181
*/
175-
public function at(int $row, int $col, int $channel, $value = null) {
182+
public function at(int $row, int $col, int $channel = 0, $value = null) {
176183

177184
}
178185

@@ -1374,7 +1381,7 @@ class Net {
13741381
* @param string $name
13751382
* @return null
13761383
*/
1377-
public function setInput(Mat $blob, string $name) {
1384+
public function setInput(Mat $blob, string $name = '') {
13781385
return null;
13791386
}
13801387

recognize_face_by_dnn_openface.php

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
3+
use CV\Scalar, CV\Size;
4+
use function CV\{imread, imwrite, rectangle};
5+
6+
$netDet = \CV\DNN\readNetFromCaffe('models/ssd/res10_300x300_ssd_deploy.prototxt', 'models/ssd/res10_300x300_ssd_iter_140000.caffemodel');
7+
$netRecogn = \CV\DNN\readNetFromTorch('models/openface/openface.nn4.small2.v1.t7');
8+
9+
$image2faces = function ($src) use ($netDet) {
10+
$size = $src->size(); // 2000x500
11+
12+
$minSide = min($size->width, $size->height);
13+
$divider = $minSide / 300;
14+
\CV\resize($src, $resized, new Size($size->width / $divider, $size->height / $divider)); // 1200x300
15+
//var_export($resized);
16+
$blob = \CV\DNN\blobFromImage($resized, 1, new Size(), new Scalar(104, 177, 123), true, false);
17+
18+
$netDet->setInput($blob);
19+
$r = $netDet->forward();
20+
21+
//var_export($r->shape);
22+
23+
$faces = [];
24+
25+
for ($i = 0; $i < $r->shape[2]; $i++) {
26+
$confidence = $r->atIdx([0,0,$i,2]);
27+
if ($confidence > 0.9) {
28+
//var_export($confidence);echo "\n";
29+
$startX = $r->atIdx([0,0,$i,3]) * $src->cols;
30+
$startY = $r->atIdx([0,0,$i,4]) * $src->rows;
31+
$endX = $r->atIdx([0,0,$i,5]) * $src->cols;
32+
$endY = $r->atIdx([0,0,$i,6]) * $src->rows;
33+
34+
$faces[] = $src->getImageROI(new \CV\Rect($startX, $startY, $endX - $startX, $endY - $startY));
35+
}
36+
}
37+
38+
return $faces;
39+
};
40+
41+
$face2vec = function ($face) use ($netRecogn) {
42+
$blob = \CV\DNN\blobFromImage($face, 1.0 / 255, new Size(96, 96), new Scalar(), true, false);
43+
$netRecogn->setInput($blob);
44+
return $netRecogn->forward();
45+
};
46+
47+
function faceDistance($face1, $face2) {
48+
$distance = 0;
49+
foreach ($face1 as $i => $v) {
50+
$distance += ($face1[$i] - $face2[$i])**2;
51+
}
52+
return sqrt($distance);
53+
}
54+
55+
$src = imread("images/faces.jpg");
56+
57+
$faces = $image2faces($src);
58+
59+
$faceVectors = [];
60+
foreach ($faces as $i => $face) {
61+
$vec = $face2vec($face);
62+
//imwrite("results/_face.jpg", $face);
63+
64+
//$vec->print();
65+
//var_export($vec->data());
66+
$faceVectors["me$i"] = $vec->data();
67+
}
68+
69+
$src = imread("images/angelina_faces.png");
70+
71+
$faces = $image2faces($src);
72+
73+
foreach ($faces as $i => $face) {
74+
$vec = $face2vec($face);
75+
//imwrite("results/_face.jpg", $face);
76+
77+
//$vec->print();
78+
//var_export($vec->data());
79+
$faceVectors["angelina$i"] = $vec->data();
80+
}
81+
82+
//var_export($faceVectors);
83+
84+
$src = imread("images/angelina_and_me.png");
85+
86+
$faces = $image2faces($src);
87+
88+
foreach ($faces as $i => $face) {
89+
$vec = $face2vec($face);
90+
$minDistance = 0;
91+
$faceLabel = '';
92+
foreach ($faceVectors as $label => $faceVector) {
93+
$distance = faceDistance($vec->data(), $faceVector);
94+
95+
if (!$minDistance || $distance < $minDistance) {
96+
$minDistance = $distance;
97+
$faceLabel = $label;
98+
}
99+
}
100+
101+
echo "face$i $faceLabel $minDistance\n";
102+
}

0 commit comments

Comments
 (0)