OpenCVに含まれる深層学習ベースの顔検出 

2022年時点で利用可能なOpenCVの顔検出・顔照合のサンプルへの記事があります。

[OpenCVに加わった深層学習ベースの顔検出・顔照合のデモ用のサンプル](https://qiita.com/waragai/items/8162bb0cb50e54d5c92b)


---
記述が古くなっていることに気づきました。
リンクが壊れています。

OpenCV のdnnの配下のスクリプトが大幅に変わったようです。

https://github.com/opencv/opencv/blob/master/modules/dnn/misc/face_detector_accuracy.py

```
# This script is used to estimate an accuracy of different face detection models.
# COCO evaluation tool is used to compute an accuracy metrics (Average Precision).
# Script works with different face detection datasets.
```

---

最近 OpenCVの中に深層学習ベースの顔検出があることに気づいた。

resnet_ssd_face_python.py
https://github.com/opencv/opencv/blob/master/samples/dnn/resnet_ssd_face_python.py


実行例
次のように打ち込むと、接続されているUSBカメラを入力として、顔検出が動作した。

```
$ cd opencv/samples/dnn
$ python resnet_ssd_face_python.py 
```

私のパソコンの環境だと
１フレームで30 ms 程度で動作した。



使用しているモデルは、次の通り。

prototxt = 'face_detector/deploy.prototxt'
caffemodel = 'face_detector/res10_300x300_ssd_iter_140000.caffemodel'


[Net cv::dnn::readNetFromCaffe(const String& prototxt, const String& caffeModel = String())]( 	
https://docs.opencv.org/3.3.1/d6/d0f/group__dnn.html#ga29d0ea5e52b1d1a6c2681e3f7d68473a)

[void cv::dnn::Net::setInput(const Mat& blob, const String& name = "" ) ](https://docs.opencv.org/3.3.1/db/d30/classcv_1_1dnn_1_1Net.html#a98ed94cb6ef7063d3697259566da310b)

[Mat cv::dnn::Net::forward( const String& outputName = String()) ](https://docs.opencv.org/3.3.1/d3/d63/classcv_1_1Mat.html)


に対応する部分が次のように簡潔になっています。

```
from cv2 import dnn

net = dnn.readNetFromCaffe(prototxt, caffemodel)

net.setInput(dnn.blobFromImage(frame, 1.0, (inWidth, inHeight), (104.0, 177.0, 123.0), False, False))
detections = net.forward()

```

setInput()
で入れる値は、4-dimensional blob from image(画像から得られる4次元のバイナリ・ラージ・オブジェクト）に変換したものが入るらしい。


```
>>> help(cv2.dnn.blobFromImage)
Help on built-in function blobFromImage:

blobFromImage(...)
    blobFromImage(image[, scalefactor[, size[, mean[, swapRB[, crop]]]]]) -> retval
    .   @brief Creates 4-dimensional blob from image. Optionally resizes and crops @p image from center,
    .   *  subtract @p mean values, scales values by @p scalefactor, swap Blue and Red channels.
    .   *  @param image input image (with 1-, 3- or 4-channels).
    .   *  @param size spatial size for output image
    .   *  @param mean scalar with mean values which are subtracted from channels. Values are intended
    .   *  to be in (mean-R, mean-G, mean-B) order if @p image has BGR ordering and @p swapRB is true.
    .   *  @param scalefactor multiplier for @p image values.
    .   *  @param swapRB flag which indicates that swap first and last channels
    .   *  in 3-channel image is necessary.
    .   *  @param crop flag which indicates whether image will be cropped after resize or not
    .   *  @details if @p crop is true, input image is resized so one side after resize is equal to corresponing
    .   *  dimension in @p size and another one is equal or larger. Then, crop from the center is performed.
    .   *  If @p crop is false, direct resize without cropping and preserving aspect ratio is performed.
    .   *  @returns 4-dimansional Mat with NCHW dimensions order.

>>> 
```

## 上記の顔検出を評価するgithub上のスクリプト（第三者による）
~~https://github.com/KatsunoriWa/eval_resnet_ssd_face~~
https://github.com/KatsunoriWa/eval_faceDetectors/tree/master/resnetSSD

resnet_ssd_face_python.py 
を改変して、個々の画像に対して検出をさせるサンプルスクリプトが次の場所にある。
しかも、いくつかのデータベースでの顔検出を評価するサンプルスクリプトが用意されている。
jupyter notebookのファイルとして実行できるようになっていて、実行結果をグラフに表示している。
検出率を算出している。
また、画像を面内回転させたときの検出率の変化も評価するようになっている。

評価の中に、誤検出に対する評価がなされていないので、評価の内容としては改善がほしいところである。

[Head Pose Image Database](http://www-prima.inrialpes.fr/perso/Gourier/Faces/HPDatabase.html) 

のように顔向きを変えたデータベースでも広い範囲で顔が検出されている。



--

学習に用いる画像データとアノテーションの与え方については次の説明を読むとよいらしい。

https://github.com/opencv/opencv/blob/master/samples/dnn/face_detector/how_to_train_face_detector.txt

(a)Download original face detection dataset 
　この学習済みの結果を得るために使われたデータベース名は明らかにされていません
(b)Convert annotation to the PASCAL VOC format 
　既存のアノテーションをPASCAL VOC format に変換します。
(c)Create LMDB database with images + annotations for training 



HaarCascadeやHOGSVMの検出器と違って、検出処理にかかる時間が、対象物（ここでは顔)の個数や、背景の紛らわしさによらないと聞いています。


[CaffeでDeep Learning つまずきやすいところを中心に](https://qiita.com/uchihashi_k/items/8333f80529bb3498e32f)

----



[OpenCVとTensorFlowを使ってリアルタイムに顔から人を識別し、結果を画面に表示する](https://qiita.com/mix_dvd/items/0688a1c4d0ecd148720a)
 
 記事を読んでみると、検出自体はOpenCVのCascadeClassifier を使っていて、人の識別の部分でTensorFlow を使っている記事だった。

---
resnet に関する記事

[ディープラーニング ResNet のヒミツ](http://terada-h.hatenablog.com/entry/2016/12/13/192940)
[Residual Network(ResNet)の理解とチューニングのベストプラクティス](https://deepage.net/deep_learning/2016/11/30/resnet.html)
[Deep Resiual Learning for Image Recognition](https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/He_Deep_Residual_Learning_CVPR_2016_paper.pdf)


github [SSD: Single Shot MultiBox Detector](https://github.com/weiliu89/caffe/tree/ssd)


[Face detection with OpenCV and Deep Learning from image-part 1](https://becominghuman.ai/face-detection-with-opencv-and-deep-learning-90b84735f421)


----

[OpenCV 以外の場所にある深層学習ベースの顔検出](https://qiita.com/nonbiri15/items/927d202e7d95e6e81ae5) を別記事にしました。


## 追記：cv2.dnn.readNetFromTensorflow() の活用
OpenCVには、代表的な深層学習の学習済みモデルを用いて推論する枠組みが用意されている。
そのため、それぞれの代表的な深層学習のフレームワークで用意されているModel Zooの結果を用いて推論することができる。

顔検出の学習済みモデルを探して、そのフレームワークでの学習済みモデルをcv2.dnnにあるライブラリを使って実行すればよい。

http://download.tensorflow.org/models/object_detection/facessd_mobilenet_v2_quantized_320x320_open_image_v4.tar.gz