如何只用兩個Python函數(shù)在幾分鐘內(nèi)創(chuàng)建完整的計算機視覺應用程序
譯文譯者 | 李睿
審校 | 重樓
本文首先概述典型的計算機視覺應用程序的要求。然后,介紹Pipeless這一為嵌入式計算機視覺提供無服務器開發(fā)體驗的開源框架。最后,提供一個詳細的步驟指南,介紹如何創(chuàng)建和執(zhí)行一個簡單的對象檢測應用程序,該應用程序只需采用幾個Python函數(shù)和一個模型進行創(chuàng)建。
創(chuàng)建計算機視覺應用程序
如果有人希望用一句話描述“計算機視覺”的話,那么給出回答是“通過攝像頭界面識別視覺事件并對其做出反應的藝術?!钡@可能不是他想聽到的答案。因此,以下將深入了解計算機視覺應用程序是如何構(gòu)建的,以及每個子系統(tǒng)需要實現(xiàn)的功能。
?真正快速的幀處理:如要實時處理60 fps的視頻流,只有16毫秒的時間來處理每幀。這在一定程度上是通過多線程和多處理進程實現(xiàn)的。在許多情況下,希望在前一個幀完成之前開始處理一個幀。
?在每一幀上運行推理并執(zhí)行對象檢測、分割、姿態(tài)估計等的人工智能模型:幸運的是,有越來越多優(yōu)秀的開源模型,所以不必從頭開始創(chuàng)建自己的模型,通常只需微調(diào)模型的參數(shù)以匹配用例。
?推理運行時間:推理運行時間負責加載模型,并在不同的可用設備(GPU或CPU)上高效運行。
?GPU:為了使模型足夠快地運行推理,我們需要采用GPU。這是因為GPU可以處理比CPU多幾個數(shù)量級的并行操作,而最低級別的模型只是大量的數(shù)學運算。你需要處理幀所在的內(nèi)存。它們可以位于 GPU 內(nèi)存或 CPU 內(nèi)存 (RAM) 中,在這些內(nèi)存之間復制幀是一項非常繁重的操作,因為幀大小會使處理速度變慢。
?多媒體管道:這些部件允許從數(shù)據(jù)源獲取視頻流,將它們分割成幀,將它們作為模型的輸入,有時修改和重建視頻流以轉(zhuǎn)發(fā)。
?視頻流管理:開發(fā)人員可能希望應用程序能夠抵抗視頻流的中斷、重新連接、動態(tài)添加和刪除視頻流、同時處理多個視頻流,等等。
所有這些系統(tǒng)都需要創(chuàng)建或合并到項目中,因此,需要維護代碼。然而,面臨的問題是最終維護的大量代碼并非特定于應用程序,而是圍繞實際案例特定代碼的子系統(tǒng)。
Pipeless框架
為了避免從頭開始構(gòu)建上述所有內(nèi)容,可以代用Pipeless框架。這是一個用于計算機視覺的開源框架,允許提供一些特定于案例的功能,并且能夠處理其他事物。
Pipeless框架將應用程序的邏輯劃分為“階段”,其中的一個階段就像單個模型的微型應用程序。一個階段可以包括預處理、使用預處理的輸入運行推理,以及對模型輸出進行后處理以采取行動。然后,可以鏈接盡可能多的階段,以組成完整的應用程序,甚至使用多個模型。
為了提供每個階段的邏輯,只需添加一個特定于應用程序的代碼函數(shù),然后在需要時由Pipeless負責調(diào)用它。這就是可以將Pipeless視為一個框架的原因,它為嵌入式計算機視覺提供類似服務器的開發(fā)體驗,并且提供了一些功能,不必擔心需要其他的子系統(tǒng)。
Pipeless的另一個重要特性是,可以通過CLI或REST API動態(tài)地添加、刪除和更新視頻流,從而實現(xiàn)視頻流處理的自動化。甚至可以指定重新啟動策略,指示何時應該重新啟動視頻流的處理,是否應該在出現(xiàn)錯誤后重新啟動,等等。
最后,部署Pipeless框架,只需要在任何設備上安裝它并與代碼函數(shù)一起運行,無論是在云計算虛擬機或容器化模式中,還是直接在Nvidia Jetson、Raspberry等邊緣設備中。
創(chuàng)建對象檢測應用程序
以下深入地了解如何使用Pipeless框架創(chuàng)建一個簡單的對象檢測應用程序。
第一就是安裝。安裝腳本,使其安裝非常簡單:
Curl https://raw.githubusercontent.com/pipeless-ai/pipeless/main/install.sh | bash
現(xiàn)在,必須創(chuàng)建一個項目。Pipeless項目是一個包含階段的目錄。每個階段都在子目錄下,在每個子目錄中,創(chuàng)建包含hooks(特定的代碼函數(shù))的文件。為每個階段文件夾提供的名稱是稍后要為視頻流運行該階段時,必須向Pipeless框指示的階段名稱。
pipeless init my-project --template empty
cd my-project
在這里,空模板告訴CLI只創(chuàng)建目錄,如果不提供任何模板,CLI將提示幾個問題以交互式地創(chuàng)建階段。
如上所述,現(xiàn)在需要為項目添加一個階段。采用下面的命令從GitHub下載一個階段示例:
wget -O - https://github.com/pipeless-ai/pipeless/archive/main.tar.gz |
tar -xz --strip=2 "pipeless-main/examples/onnx-yolo"
這將創(chuàng)建一個階段目錄onnx-yolo,其中包含應用程序函數(shù)。
然后,檢查每個階段文件的內(nèi)容,也就是應用程序hooks。
這里有一個pre-process.py文件,它定義了一個接受一個框架和一個場景的函數(shù)(hooks)。該函數(shù)執(zhí)行一些操作來準備接收RGB幀的輸入數(shù)據(jù),以便與模型期望的格式匹配。該數(shù)據(jù)被添加到frame_data[' interence_input ']中,這是Pipeless將傳遞給模型的數(shù)據(jù)。
def hook(frame_data, context):
frame = frame_data["original"].view()
yolo_input_shape = (640, 640, 3) # h,w,c
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame = resize_rgb_frame(frame, yolo_input_shape)
frame = cv2.normalize(frame, None, 0.0, 1.0, cv2.NORM_MINMAX)
frame = np.transpose(frame, axes=(2,0,1)) # Convert to c,h,w
inference_inputs = frame.astype("float32")
frame_data['inference_input'] = inference_inputs
... (some other auxiliar functions that we call from the hook function)
還有process.json文件,它指示要使用的Pipeless推理運行時間(在本例中為ONNX運行時間),在哪里可以找到它應該加載的模型,以及它的一些可選參數(shù),例如要使用的execution_provider,即CPU、CUDA、TensortRT等。
{
"runtime": "onnx",
"model_uri": "https://pipeless-public.s3.eu-west-3.amazonaws.com/yolov8n.onnx",
"inference_params": {
"execution_provider": "tensorrt"
}
}
最后,post-process.py文件定義了一個類似于pre-process.py中的函數(shù)。這一次,它接受Pipeless存儲在frame_data["inference_output"]中的推理輸出,并執(zhí)行將該輸出解析為邊界框的操作。稍后,它在框架上繪制邊界框,最后將修改后的框架分配給frame_data['modified']。這樣,Pipeless將轉(zhuǎn)發(fā)提供的視頻流,但帶有修改后的幀,其中包括邊界框。
def hook(frame_data, _):
frame = frame_data['original']
model_output = frame_data['inference_output']
yolo_input_shape = (640, 640, 3) # h,w,c
boxes, scores, class_ids =
parse_yolo_output(model_output, frame.shape, yolo_input_shape)
class_labels = [yolo_classes[id] for id in class_ids]
for i in range(len(boxes)):
draw_bbox(frame, boxes[i], class_labels[i], scores[i])
frame_data['modified'] = frame
... (some other auxiliar functions that we call from the hook function)
最后一步是啟動Pipeless并提供一個視頻流。要啟動Pipeless,只需在my-project目錄下運行以下命令:
pipeless start --stages-dir .
一旦運行,將提供來自網(wǎng)絡攝像頭(v4l2)的視頻流,并直接在屏幕上顯示輸出。需要注意的是,必須提供視頻流按順序執(zhí)行的階段列表。在這個例子中,它只是onnx-yolo階段:
pipeless add stream --input-uri "v4l2" --output-uri "screen" --frame-path "onnx-yolo"
結(jié)論
創(chuàng)建計算機視覺應用程序是一項復雜的任務,因為有許多因素和必須圍繞它實現(xiàn)的子系統(tǒng)。使用像Pipeless這樣的框架,啟動和運行只需要幾分鐘,可以專注于為特定用例編寫代碼。此外,Pipeless的“階段”是高度可重用的,易于維護,因此維護將會很容易,可以非??焖俚氐?/span>
如果希望參與Pipeless的開發(fā),可以通過它的GitHub存儲庫來實現(xiàn)。
原文標題:Create a Complete Computer Vision App in Minutes With Just Two Python Functions,作者:Miguel Angel Cabrera
鏈接:https://dzone.com/articles/creating-a-complete-computer-vision-application-in