diff --git a/detect_facemarks_by_dnn_vanface.php b/detect_facemarks_by_dnn_vanface.php new file mode 100644 index 0000000..0dad48f --- /dev/null +++ b/detect_facemarks_by_dnn_vanface.php @@ -0,0 +1,59 @@ +size(); // 2000x500 + +$minSide = min($size->width, $size->height); +$divider = $minSide / 300; +\CV\resize($src, $resized, new Size($size->width / $divider, $size->height / $divider)); // 1200x300 + +//var_export($resized); + +$blob = \CV\DNN\blobFromImage($resized, 1, new Size(), new Scalar(104, 177, 123), true, false); + +$netDet->setInput($blob); + +$r = $netDet->forward(); + +//var_export($r->shape); + +$faces = []; +$scalar = new Scalar(0, 0, 255); +for ($i = 0; $i < $r->shape[2]; $i++) { + $confidence = $r->atIdx([0,0,$i,2]); + if ($confidence > 0.9) { + var_export($confidence);echo "\n"; + $startX = $r->atIdx([0,0,$i,3]) * $src->cols; + $startY = $r->atIdx([0,0,$i,4]) * $src->rows; + $endX = $r->atIdx([0,0,$i,5]) * $src->cols; + $endY = $r->atIdx([0,0,$i,6]) * $src->rows; + + $face = $src->getImageROI(new \CV\Rect($startX, $startY, $endX - $startX, $endY - $startY)); + \CV\resize($face, $resized, new Size(60,60)); + $resized = cvtColor($resized, \CV\COLOR_BGR2GRAY, 2); + \CV\meanStdDev($resized, $mean, $sdv); + + $m = $mean->data()[0]; + $s = $sdv->data()[0]; + + $blob = \CV\DNN\blobFromImage($resized, 1 / (0.000001 + $s), new Size(60,60), new Scalar($m, $m, $m)); + $netRecogn->setInput($blob); + //var_export($blob);die(); + $out = $netRecogn->forward(); + $data = $out->data(); + + for ($j=0;$j<68;$j++) { + $point = new \CV\Point($startX + $data[$j*2] * $face->cols, $startY + $data[$j*2+1] * $face->rows); + circle($src, $point, 2, new Scalar(0, 0, 255), 2); + //var_export($point); + } + } +} + +imwrite("results/_detect_facemarks_by_dnn_vanface.jpg", $src); diff --git a/models/README.md b/models/README.md index 1be71b4..eec0782 100644 --- a/models/README.md +++ b/models/README.md @@ -10,3 +10,4 @@ Sources: * ssdlite_mobilenet_v2_coco - https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md * ssd_mobilenet_v2_coco - https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md * insightface - https://github.com/axinc-ai/ailia-models/tree/master/face_identification/insightface +* VanFace - https://github.com/lsy17096535/face-landmark diff --git a/models/VanFace/VanFace.caffemodel b/models/VanFace/VanFace.caffemodel new file mode 100644 index 0000000..2b7343f Binary files /dev/null and b/models/VanFace/VanFace.caffemodel differ diff --git a/models/VanFace/VanFace.prototxt b/models/VanFace/VanFace.prototxt new file mode 100644 index 0000000..3b0e4d4 --- /dev/null +++ b/models/VanFace/VanFace.prototxt @@ -0,0 +1,290 @@ +name: "landmark" +input: "data" +input_dim: 1 +input_dim: 1 +input_dim: 60 +input_dim: 60 +######################################## +# the actual net +# layer 1 +layer { + name: "Conv1" + type: "Convolution" + bottom: "data" + top: "Conv1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 20 + pad: 2 + kernel_size: 5 + stride: 1 + weight_filler { + type: "xavier" + std: 0.1 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} + +layer { + name: "ActivationTangH1" + bottom: "Conv1" + top: "ActivationTangH1" + type: "TanH" +} + +layer { + name: "ActivationAbs1" + bottom: "ActivationTangH1" + top: "Abs1" + type: "AbsVal" +} + +layer { + name: "Pool1" + type: "Pooling" + bottom: "Abs1" + top: "Pool1" + pooling_param { + pool: MAX + kernel_size: 2 + stride: 2 + } +} + +layer { + name: "Conv2" + type: "Convolution" + bottom: "Pool1" + top: "Conv2" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 48 + pad: 2 + kernel_size: 5 + stride: 1 + weight_filler { + type: "xavier" + std: 0.1 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} + +layer { + name: "ActivationTangH2" + bottom: "Conv2" + top: "ActivationTangH2" + type: "TanH" +} + +layer { + name: "ActivationAbs2" + bottom: "ActivationTangH2" + top: "Abs2" + type: "AbsVal" +} + + +layer { + name: "Pool2" + type: "Pooling" + bottom: "Abs2" + top: "Pool2" + pooling_param { + pool: MAX + kernel_size: 2 + stride: 2 + } +} + +# layer 3 +layer { + name: "Conv3" + type: "Convolution" + bottom: "Pool2" + top: "Conv3" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + pad: 0 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + std: 0.1 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} + + +layer { + name: "ActivationTangH3" + bottom: "Conv3" + top: "ActivationTangH3" + type: "TanH" +} + +layer { + name: "ActivationAbs3" + bottom: "ActivationTangH3" + top: "Abs3" + type: "AbsVal" +} + +layer { + name: "Pool3" + type: "Pooling" + bottom: "Abs3" + top: "Pool3" + pooling_param { + pool: MAX + kernel_size: 3 + stride: 2 + } +} + +# layer 4 +layer { + name: "Conv4" + type: "Convolution" + bottom: "Pool3" + top: "Conv4" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 80 + pad: 0 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + std: 0.1 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} + + +layer { + name: "ActivationTangH4" + bottom: "Conv4" + top: "ActivationTangH4" + type: "TanH" +} + +layer { + name: "ActivationAbs4" + bottom: "ActivationTangH4" + top: "Abs4" + type: "AbsVal" +} + + +######################################## + +layer { + name: "Dense1" + type: "InnerProduct" + bottom: "Abs4" + top: "Dense1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + inner_product_param { + num_output: 512 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} + + +layer { + name: "ActivationTangH5" + bottom: "Dense1" + top: "ActivationTangH5" + type: "TanH" +} + +layer { + name: "ActivationAbs5" + bottom: "ActivationTangH5" + top: "Abs5" + type: "AbsVal" +} + + +layer { + name: "Dense3" + type: "InnerProduct" + bottom: "Abs5" + top: "Dense3" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + inner_product_param { + num_output: 136 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} diff --git a/results/detect_facemarks_by_dnn_vanface.jpg b/results/detect_facemarks_by_dnn_vanface.jpg new file mode 100644 index 0000000..697fccd Binary files /dev/null and b/results/detect_facemarks_by_dnn_vanface.jpg differ