我們嘗試模塊化并分離管道構建塊,這種方法將為我們提供易于管理的代碼,并使測試更容易編寫:
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類的批量處理大?。?/p>
$ 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幀。
-
攝像頭
+關注
關注
59文章
4836瀏覽量
95600 -
OpenCV
+關注
關注
31文章
634瀏覽量
41338 -
JSON
+關注
關注
0文章
117瀏覽量
6963
發布評論請先 登錄
相關推薦
評論