訂閱
糾錯(cuò)
加入自媒體

DVG-Utils工具,幫你快速構(gòu)建圖像和視頻處理管道

dvg-utils是一組工具,可以幫助你使用OpenCV快速構(gòu)建圖像和視頻處理管道。

在不同的平臺和設(shè)備上進(jìn)行計(jì)算機(jī)視覺和深度學(xué)習(xí)的實(shí)驗(yàn)帶來了許多挑戰(zhàn),尤其是當(dāng)你希望與團(tuán)隊(duì)共同維護(hù)一個(gè)代碼庫而不需要做重復(fù)的工作。從不同設(shè)備設(shè)置視頻流的步驟基本上是一樣的,該過程我們需要記錄日志,讀取配置文件,繪制帶有標(biāo)簽的框,保存結(jié)果,收集一些指標(biāo)等,為什么不將這些工作放在一起呢?這就是本文向你介紹dvg-utils的意義。目錄dvg-utils簡介設(shè)置命令行工具捕獲視頻捕獲圖像例子指標(biāo)概要資源dvg-utils簡介自從我寫了第一篇關(guān)于為圖像和視頻處理創(chuàng)建一個(gè)模塊化而且簡單的管道的文章以來,差不多過去一年了,從那以后我也一直在學(xué)習(xí),學(xué)到了很多東西。在這段時(shí)間里,我做了許多不同的項(xiàng)目,它們總是需要相同的步驟。每個(gè)計(jì)算機(jī)視覺管道都需要以下代碼塊:設(shè)置日志讀取配置文件捕獲圖像或視頻流處理數(shù)據(jù)可視化結(jié)果顯示結(jié)果保存結(jié)果收集指標(biāo)這些代碼塊中的大多數(shù)都是在每個(gè)項(xiàng)目中會反復(fù)出現(xiàn)的模板代碼。為了更輕松,更快速地設(shè)置計(jì)算機(jī)視覺項(xiàng)目,我在S?awomirGilewski的幫助下創(chuàng)建了dvg-utils Python軟件包。dvg-utils:https://github.com/jagin/dvg-utilsS?awomirGilewski:https://medium.com/u/1ddaceb8aa71設(shè)置在開始之前,我建議使用Python虛擬環(huán)境。虛擬環(huán)境允許你在系統(tǒng)上運(yùn)行獨(dú)立的Python環(huán)境,更多請看一下RealPython上的這篇文章。https://realpython.com/python-virtual-environments-a-primer/我假設(shè)你正在使用具有Linux或MacOs系統(tǒng)的臺式機(jī)/筆記本電腦(我沒有機(jī)會在Windows平臺上對其進(jìn)行測試,但它應(yīng)該可以運(yùn)行)。如果你想從Jetson設(shè)備運(yùn)行一些示例,Jetpack的SDK已經(jīng)安裝了OpenCV,你可以跳過pip install opencv-contrib-python這一步驟。對于樹莓派用戶,請?jiān)诖宋恼碌膸椭掳惭bOpenCV 。https://www.pyimagesearch.com/2019/09/16/install-opencv-4-on-raspberry-pi-4-and-raspbian-buster/為了瀏覽庫和用法示例,讓我們克隆它并安裝所需的軟件包:$ git clone https://github.com/jagin/dvg-utils.git

$ cd ./dvg-utils

$ pip install tqdm pyyaml numpy

$ pip install opencv-contrib-python

$ pip install dvg-utils

命令行工具安裝dvg-utils后,你可以訪問dvg-utils工具命令:將視頻文件轉(zhuǎn)換為一組圖像$ dvg-utils v2i -i assets/videos/faces.mp4 -o output --display

將一組幀圖像轉(zhuǎn)換為視頻文件$ dvg-utils i2v -i output -o output/my_new_file.a(chǎn)vi --display

繪制指標(biāo)(我將在本故事的后面部分對此進(jìn)行詳細(xì)介紹)對于參數(shù)描述,請運(yùn)行以下命令之一:$ dvg-utils v2i -h(huán)

$ dvg-utils i2v -h(huán)

$ dvg-utils pm -h(huán)

如果可以分別處理每一幀,則將視頻轉(zhuǎn)換為圖像并返回,你可以并行處理這些幀,然后將它們組合回帶有可視注釋的視頻文件中。捕獲視頻dvg-utils的強(qiáng)大功能來自于從OpenCV cv2.VideoCapture和樹莓派相機(jī)支持的所有源捕獲視頻流,使用單線:video_capture = VideoCapture(conf["videoCapture"]).open()

技巧是使用conf["videoCapture"],其中包含我們的視頻捕獲配置的字典,該字典從YAML配置文件中讀取,參考:https://medium.com/swlh/python-yaml-configuration-with-environment-variables-parsing-77930f4273ac (向Maria Karanasou致謝,她使用環(huán)境變量parsing進(jìn)行了Python YAML配置)videoCapture:
 capture: file
 file:
   src: assets/videos/cars_driving.mp4
   # You can select the frame range for a video file
   # start_frame: 100
   # end_frame: 500
 camera:
   src: 0
   fourcc: MJPG
   resolution: [640, 480]
   fps: 30
 piCamera:
   src: 0
   resolution: [640, 480]
   framerate: 30
   settings:
     rotation: 180
 stream:
   # Jetson Nano camera stream
   src: >-
     nvarguscamerasrc sensor-id=0 sensor_mode=3 !
     video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12, framerate=(fraction)30/1 !
     nvvidconv flip-method=2 !
     video/x-raw, width=(int)640, height=(int)480, format=(string)BGRx !
     videoconvert !
     video/x-raw, format=(string)BGR !
     appsink
   api_preference: CAP_GSTREAMER

我們可以定義不同的來源(file,camera,piCamera,stream),但我們想要選擇的屬性在videoCapture.capture里面(在上面的例子中是assets/videos/cars_driving.mp4文件)。讓我們運(yùn)行./examples/capture_video.py示例以查看實(shí)際效果:$ python ./examples/capture_video.py
INFO: Load configuration from config/capture_video.yml
INFO: Capturing file: assets/videos/cars_driving.mp4
INFO: Codec: avc1
INFO: Resolution: 1280x720
INFO: FPS: 50.0
INFO: Capturing...
INFO: 3000 it, 13.106 s, 0.004 s/it, 228.89 it/s
3000it [00:13, 228.88it/s]

這個(gè)簡單的例子是你學(xué)習(xí)視頻處理管道的一個(gè)很好的起點(diǎn)。它已經(jīng)包括:配置文件 config/capture_video.yml,它規(guī)定可在不同平臺上使用的不同的視頻源記錄器來顯示可用信息:記錄器選項(xiàng)在 logger.yml 文件中定義,我們通過 setup_logger() 從 dvgutil 包中調(diào)用函數(shù)來進(jìn)行設(shè)置,顯示帶有處理后的幀數(shù)和預(yù)測的FPS結(jié)果:dvgutils.vis帶有helper函數(shù)的程序包可以很好地放置一些文本,繪制覆蓋矩形或調(diào)整圖像大小,并保留長寬比或填充,保存帶注釋的輸出視頻選項(xiàng):包中有SaveVideo和SaveImage類,dvgutils.modules可輕松保存視頻和圖像,用于保存有關(guān)管道性能的指標(biāo)選項(xiàng):通過包中的Metrics類,dvgutils.modules可以收集指標(biāo)(如迭代時(shí)間,每秒迭代次數(shù),每次迭代的秒數(shù)),你可以使用dvg-utils pm命令進(jìn)行繪制。這是完整的選項(xiàng)列表:$ python ./examples/capture_video.py -h(huán)
usage: capture_video.py [-h(huán)] [-cf CONF]
                       [-cfo CONF_OVERWRITES [CONF_OVERWRITES ...]]
                       [-o OUTPUT] [--no-display] [--no-progress]
                       [--pipeline] [--metrics METRICS] [--fps FPS]
optional arguments:
 -h(huán), --h(huán)elp            show this help message and exit
 -cf CONF, --conf CONF
                       Path to the input configuration file (default:
                       config/capture_video.yml)
 -cfo CONF_OVERWRITES [CONF_OVERWRITES ...], --conf-overwrites CONF_OVERWRITES [CONF_OVERWRITES ...]
 -o OUTPUT, --output OUTPUT
                       output video file name
 --no-display          hide display window
 --no-progress         don't display progress
 --pipeline            run as pipeline
 --metrics METRICS     metrics file name
 --fps FPS             output video fps

之前我提到過,我們可以使用其他輸入源來運(yùn)行管道。如何實(shí)現(xiàn)呢?有兩種方法:在config/capture_video.yml部分設(shè)置capture屬性videoCapture到選定的源(file,camera,piCamera,stream)使用選項(xiàng)-cfo videoCapture.capture=<selected_source>執(zhí)行管道,該選項(xiàng)將覆蓋YAML配置中的設(shè)置。要使用網(wǎng)絡(luò)攝像頭執(zhí)行示例,請運(yùn)行:$ python ./examples/capture_video.py -cfo videoCapture.capture=camera

如果你在樹莓派上運(yùn)行示例,則需要在樹莓派上運(yùn)行pip install picamera。你可以通過在顯示屏上按ESC(只是將其關(guān)閉或在終端中按Ctrl + C)來中斷該處理,所有這些操作都在dvgutils.modules的ShowImage類中處理。capture_video.py示例包含兩個(gè)不同的實(shí)現(xiàn)方式,用于說明目的。第一個(gè)是一個(gè)簡單的while循環(huán),其中我們使用dvg-utils包中的通用類處理視頻幀:# Setup processing modules
video_capture = VideoCapture(conf["videoCapture"]).open()
save_video = SaveVideo(args["output"])
show_image = ShowImage("Video")
metrics = Metrics().start()
progress = Progress(disable=not args["progress"])
while True:
   # Grab the frame
   frame = video_capture.read()
   if frame is None:
       break
   ... # Do some processing and visualization
   save_video(frame)
   show = show_image(frame)
   if not show:
       break
   metrics.update()
   progress.update()
   idx += 1

第二個(gè)基于流水線的概念,在流水線的概念中,我們定義了處理塊,并借助Python生成器將數(shù)據(jù)推送到該流(CaptureVideoPipe是一個(gè)生成器,生成的幀數(shù)據(jù)通過管道步驟進(jìn)行映射)。# Setup pipeline steps
capture_video_pipe = CaptureVideoPipe(conf["videoCapture"])
save_video_pipe = SaveVideoPipe("vis_image", args["output"])
show_image_pipe = ShowImagePipe("vis_image", "Video")
metrics_pipe = MetricsPipe()
progress_pipe = ProgressPipe(disable=not args["progress"])
# Create pipeline
pipeline = Pipeline(capture_video_pipe)
pipeline.map(...)  # Do some processing and visualization
pipeline.map(save_video_pipe)
pipeline.map(show_image_pipe)
pipeline.map(metrics_pipe)
pipeline.map(progress_pipe)
# Process pipeline
pipeline.run()

創(chuàng)建模塊化管道可以使我們有機(jī)會在不同項(xiàng)目中重用通用塊。捕獲圖像使用dvg-utils,你可以幾乎以與視頻幀相同的方式來處理圖像。examples/capture_image.py是一個(gè)很好的示例。使用以下配置(config/capture_image.yml):imageCapture:
 path: assets/images/friends
 valid_ext: jpg
 #contains: some_string
 # Transform image
 transform:
   resize:
     width: 320
   flip: 1  # 0 - vertical, 1 - horizontal, -1 - vertical and horizontal
你可以從assets/images/friends目錄中讀取所有JPG文件,甚至在它們運(yùn)行你的處理代碼之前對其進(jìn)行轉(zhuǎn)換:$ python ./examples/capture_image.py

例子dvg-utils包含許多示例,這些示例說明了如何構(gòu)建圖像或視頻處理管道。讓我們在 examples 文件夾中看看其中的一些示例。對象檢測我們可以使用以下命令運(yùn)行對象檢測示例:$ python ./examples/detect_object_video.py
INFO: Load configuration from config/detect_object_video.yml
INFO: Capturing file: assets/videos/people_walking.mp4
INFO: Codec: avc1
INFO: Resolution: 402x300
INFO: FPS: 30.0
INFO: Capturing...
INFO: 1283 it, 54.567 s, 0.043 s/it, 23.51 it/s
1283it [00:54, 23.51it/s]

該示例默認(rèn)情況下會檢測行人。

只需進(jìn)行少量配置,即可在需要時(shí)檢測汽車:$ python ./examples/detect_object_video.py -cfo videoCapture.file.src=assets/videos/cars_driving.mp4 objectDetector.caffe.classes=["cars"]
detect_object_video.py在examples/modules/object_detector/caffe_object_detector.py中使用Caffe MobileNet-SSD模型,并在config/detect_object_video.yml中進(jìn)行配置(請參閱objectDetector部分)。Caffe MobileNet-SSD:https://github.com/chuanqi305/MobileNet-SSD對象跟蹤要跟蹤對象,我們需要先對其進(jìn)行檢測。我們已經(jīng)有了對象檢測器,可以在跟蹤管道中重用它(此示例需要pip install scipy dlib):$ python ./examples/track_object_video.py
INFO: Load configuration from config/track_object_video.yml
INFO: Capturing file: assets/videos/people_walking.mp4
INFO: Codec: avc1
INFO: Resolution: 402x300
INFO: FPS: 30.0
INFO: Capturing...
INFO: 1283 it, 11.233 s, 0.009 s/it, 114.21 it/s
1283it [00:11, 114.17it/s]

在我們的例子中,我們可以使用管道來實(shí)現(xiàn)這兩種目標(biāo)跟蹤算法。一個(gè)基于OpenCV Tracking API (默認(rèn)使用KCF tracker),第二個(gè)基于Dlib包。你可以通過在config/track_object_video.yml中改變objectTracker.tracker 設(shè)置來激活它,或者運(yùn)行:$ python ./examples/track_object_video.py -cfo objectTracker.tracker=dlib

以下文章對兩種跟蹤器都有很好的解釋:使用OpenCV跟蹤對象https://www.learnopencv.com/object-tracking-using-opencv-cpp-python/使用dlib進(jìn)行對象跟蹤https://www.pyimagesearch.com/2018/10/22/object-tracking-with-dlib/這個(gè)例子說明了嘗試不同算法是多么容易。對象計(jì)數(shù)目標(biāo)檢測是跟蹤的基礎(chǔ),目標(biāo)跟蹤是對被定義的虛擬線中的對象進(jìn)行計(jì)數(shù)。這條線可能是商店的入口,而目標(biāo)可能是一個(gè)人,所有這些我們都可以在不觸及代碼行的情況下進(jìn)行配置。要查看運(yùn)行中的對象計(jì)數(shù)器,請執(zhí)行以下操作:$ python ./examples/count_object_video.py
INFO: Load configuration from config/count_object_video.yml
INFO: Capturing file: assets/videos/people_walking.mp4
INFO: Codec: avc1
INFO: Resolution: 402x300
INFO: FPS: 30.0
INFO: Capturing...
INFO: 1283 it, 11.631 s, 0.009 s/it, 110.31 it/s
1283it [00:11, 110.27it/s]  

本文很好地描述了此示例的思想:OpenCV人群計(jì)數(shù)https://www.pyimagesearch.com/2018/08/13/opencv-people-counter/但我將其擴(kuò)展為可以在圖像的任何位置定義任何行(多虧有dvgutils.vis)

聲明: 本文由入駐維科號的作者撰寫,觀點(diǎn)僅代表作者本人,不代表OFweek立場。如有侵權(quán)或其他問題,請聯(lián)系舉報(bào)。

發(fā)表評論

0條評論,0人參與

請輸入評論內(nèi)容...

請輸入評論/評論長度6~500個(gè)字

您提交的評論過于頻繁,請輸入驗(yàn)證碼繼續(xù)

  • 看不清,點(diǎn)擊換一張  刷新

暫無評論

暫無評論

人工智能 獵頭職位 更多
掃碼關(guān)注公眾號
OFweek人工智能網(wǎng)
獲取更多精彩內(nèi)容
文章糾錯(cuò)
x
*文字標(biāo)題:
*糾錯(cuò)內(nèi)容:
聯(lián)系郵箱:
*驗(yàn) 證 碼:

粵公網(wǎng)安備 44030502002758號