OpenCV的视频处理之人脸检测 2

电子说

1.3w人已加入

描述

我们尝试模块化并分离管道构建块,这种方法将为我们提供易于管理的代码,并使测试更容易编写:

import os
import cv2


from pipeline.libs.face_detector import FaceDetector
import tests.config as config




class TestFaceDetector:
    def test_face_detector(self):
        prototxt = os.path.join(config.MODELS_FACE_DETECTOR_DIR, "deploy.prototxt.txt")
        model = os.path.join(config.MODELS_FACE_DETECTOR_DIR, "res10_300x300_ssd_iter_140000.caffemodel")
        detector = FaceDetector(prototxt, model)


        test_image = cv2.imread(os.path.join(config.ASSETS_IMAGES_DIR, "friends", "friends_01.jpg"))
        faces = detector.detect([test_image])


        assert len(faces) == 1
        assert len(faces[0])  # Should recognize some faces from friends_01.jpg

使用管道架构,可以很容易地CascadeDetectFaces从上一篇文章换成更准确的深度学习人脸检测器模型。让我们FaceDetector在新的DetectFaces管道步骤中使用:

from pipeline.pipeline import Pipeline
from pipeline.libs.face_detector import FaceDetector


class DetectFaces(Pipeline):
    def __init__(self, prototxt, model, batch_size=1, confidence=0.5):
        self.detector = FaceDetector(prototxt, model, confidence=confidence)
        self.batch_size = batch_size


        super(DetectFaces, self).__init__()


    def generator(self):
        batch = []
        stop = False
        while self.has_next() and not stop:
            try:
                # Buffer the pipeline stream
                data = next(self.source)
                batch.append(data)
            except StopIteration:
                stop = True


            # Check if there is anything in batch.
            # Process it if the size match batch_size or there is the end of the input stream.
            if len(batch) and (len(batch) == self.batch_size or stop):
                # Prepare images batch
                images = [data["image"] for data in batch]
                # Detect faces on all images at once
                faces = self.detector.detect(images)


                # Extract the faces and attache them to the proper image
                for image_idx, image_faces in faces.items():
                    batch[image_idx]["faces"] = image_faces


                # Yield all the data from buffer
                for data in batch:
                    if self.filter(data):
                        yield self.map(data)


                batch = []

我们对图像流(第15–20行)进行缓冲,直到到达batch_size(第24行)为止,然后在所有缓冲的图像上(第28行)检测面部,收集面部坐标和置信度(第31–32行),然后重新生成图像(第35-37行)。

当我们使用GPU(图形处理单元)时,我们的武器库中同时运行着数千个处理内核,这些内核专门用于矩阵运算。批量执行推理总是更快,一次向深度学习模型展示的图像多于一张一张。

保存面孔和摘要

SaveFaces并SaveSummary产生输出结果。在SaveFaces类,使用map功能,遍历所有检测到的面部,从图像裁剪他们并保存到输出目录。

SaveSummary类的任务是收集有关已识别面部的所有元数据,并将它们保存为结构良好的JSON文件,该map函数用于缓冲元数据。接下来,我们使用额外的write功能扩展我们的类,我们将需要在管道的末尾触发以将JSON文件与摘要一起保存。脸部图像针对每一帧存储在单独的目录中。

视频输出

为了观察流水线的结果,很高兴可以显示带有带注释的面孔的视频。关于AnnotateImage(pipeline/annotate_image.py)/DisplayVideo(pipeline/display_video.py)的全部内容。

运行中的管道

在process_video_pipeline.py文件中我们可以看到,整个管道的定义如下:

pipeline = (capture_video |
            detect_faces |
            save_faces |
            annotate_image |
            display_video |
            save_video |
            save_summary)

上面有很多解释,但是视频和图像胜于雄辩。让我们来看一下触发命令的管道:

python process_video_pipeline.py -i assets/videos/faces.mp4 -p -d -ov faces.avi,M,];

-p将显示进度条,

-d显示带有批注面孔的视频结果,

-ov faces.avi并将视频结果保存到output文件夹。

正如我们在示例视频中看到的那样,并不是所有脸孔都能被识别。我们可以降低设置参数的深度学习模型的置信度confidence 0.2(默认值为0.5)。降低置信度阈值会增加假阳性的发生(在图像中没有脸的位置出现脸)。

DetectFaces类的批量处理大小:

$ python process_video_pipeline.py -i assets/videos/faces.mp4 -p
--batch-size 1
100%|███████████████████████████| 577/577 [00:11<00:00, 52.26it/s]
[INFO] Saving summary to output/summary.json...


$ python process_video_pipeline.py -i assets/videos/faces.mp4 -p
--batch-size 4
100%|███████████████████████████| 577/577 [00:09<00:00, 64.66it/s]
[INFO] Saving summary to output/summary.json...
$ python process_video_pipeline.py -i assets/videos/faces.mp4 -p
--batch-size 8
100%|███████████████████████████| 577/577 [00:10<00:00, 56.04it/s]
[INFO] Saving summary to output/summary.json...

在我们的硬件上(2.20GHz的Core i7–8750H CPU和NVIDIA RTX 2080 Ti),我门每秒获得52.26帧的图像--batch-size 1,但是对于--batch-size 4我们来说,速度却提高到了每秒64.66帧。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分