實戰:使用 PyTorch 和 OpenCV 實現實時目標檢測系統

點擊下方AI算法與圖像處理”,一起進步!

重磅乾貨,第一時間送達


   
   
   


一、引言
自動駕駛汽車可能仍然難以理解人類和垃圾桶之間的區別,但這並沒有使最先進的物體檢測模型在過去十年中取得的驚人進步相去甚遠。


將其與 OpenCV 等庫的圖像處理能力相結合,如今在數小時內構建實時對象檢測系統原型要容易得多。在本指南中,我們將嘗試向您展示如何開發用於簡單對象檢測應用程序的子系統,以及如何將所有這些組合在一起。


二、Python與C++


我知道你們中的一些人可能會想,爲什麼我們要使用Python,在某種程度上,它對於實時應用程序來說不是太慢了嗎。


大多數計算重操作,如預測或圖像處理,都是通過PyTrand和OpenCV來執行的,它們都使用C++在場景後面實現這些操作,因此,如果我們在這裏使用C++或Python,則不會有太大的差別。



三、讀取視頻流


輸入的視頻源可以是任何內容,從網絡攝像頭讀取,或解析現有視頻,或從連接到網絡的外部攝像頭。在此示例中,我們將展示如何從 youtube 或網絡攝像頭讀取視頻流。


四、從YouTube讀取


你們可能不想出去創建新視頻,而是使用許多在線可用的視頻。在這種情況下,你們可以從 youtube 讀取視頻流。

import cv2 # opencv2 package for python.import pafy # pafy allows us to read videos from youtube.URL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ" #URL to parseplay = pafy.new(self._URL).streams[-1] #'-1' means read the lowest quality of video.assert play is not None # we want to make sure their is a input to read.stream = cv2.VideoCapture(play.url) #create a opencv video stream.


五、從網絡攝像頭讀取


import cv2stream = cv2.VideoCapture(0) # 0 means read from local camera.


六、讀取IP攝像頭


如果你們正在構建將部署在服務器上的應用程序,攝像機擁有一個自己的 IP 地址,你可以從中訪問視頻流。

import cv2camera_ip = "rtsp://username:password@IP/port"stream = cv2.VideoCapture(camera_ip)


七、加載模型


有許多不錯的對象檢測模型,每個模型都有其優點和缺點。爲了簡單起見,我們將使用YoloV5,因爲它爲我們提供了對我們的實時應用程序至關重要的快速應用。你們還可以查看其他模型,例如 FasterRCNN。


我們可以直接從 PyTorch hub 加載模型,第一次運行代碼可能需要幾分鐘,因爲它會從互聯網上下載模型,但下次它將直接從磁盤加載。

from torch import hub # Hub contains other models like FasterRCNNmodel = torch.hub.load( \                      'ultralytics/yolov5', \                      'yolov5s', \                      pretrained=True)


八、單幀評分


我們可以說“解析一個視頻流,從一幀開始”。那麼讓我們看看如何對單個幀進行評分和解析。我們用來執行應用的設備對我們的應用速度產生了巨大的影響,現代深度學習模型在使用 GPU 時效果最好,因此如果你們有一個帶有 CUDA 內核的 GPU,它將大大提高您的性能。根據經驗,即使是單個 GPU 的系統也可以達到每秒 45-60 幀,而 CPU 最多隻能提供 25-30 幀。

"""The function below identifies the device which is availabe to make the prediction and uses it to load and infer the frame. Once it has results it will extract the labels and cordinates(Along with scores) for each object detected in the frame."""def score_frame(frame, model):    device = 'cuda' if torch.cuda.is_available() else 'cpu'    model.to(device)    frame = [torch.tensor(frame)]    results = self.model(frame)    labels = results.xyxyn[0][:, -1].numpy()    cord = results.xyxyn[0][:, :-1].numpy()    return labels, cord
九、繪製試別對象及框架


一旦我們對幀進行了評分,在將幀寫入輸出流之前,我們需要在幀上繪製識別的對象及其框。爲此,我們可以使用 OpenCV 的圖像處理工具包。

"""The function below takes the results and the frame as input and plots boxes over all the objects which have a score higer than our threshold."""def plot_boxes(self, results, frame):    labels, cord = results    n = len(labels)    x_shape, y_shape = frame.shape[1], frame.shape[0]    for i in range(n):        row = cord[i]        # If score is less than 0.2 we avoid making a prediction.        if row[4] < 0.2:             continue        x1 = int(row[0]*x_shape)        y1 = int(row[1]*y_shape)        x2 = int(row[2]*x_shape)        y2 = int(row[3]*y_shape)        bgr = (0, 255, 0) # color of the box        classes = self.model.names # Get the name of label index        label_font = cv2.FONT_HERSHEY_SIMPLEX #Font for the label.        cv2.rectangle(frame, \                      (x1, y1), (x2, y2), \                       bgr, 2) #Plot the boxes        cv2.putText(frame,\                    classes[labels[i]], \                    (x1, y1), \                    label_font, 0.9, bgr, 2) #Put a label over box.        return frame


十、輸出




十一、整合


現在我們將它們整合到一個調用函數中,在循環中執行整個操作,讓我們回顧一下我們的主要功能必須執行以成功運行應用程序的步驟。

  1. 創建視頻流輸入。
  2. 加載模型。
  3. 當輸入可用時,閱讀下一幀。
  4. 對框架進行評分以獲取標籤和座標。
  5. 在檢測到的對象上繪製框。
  6. 將處理後的幀寫入輸出視頻流。
"""The Function below oracestrates the entire operation and performs the real-time parsing for video stream."""def __call__(self):    player = self.get_video_stream() #Get your video stream.    assert player.isOpened() # Make sure that their is a stream.     #Below code creates a new video writer object to write our    #output stream.    x_shape = int(player.get(cv2.CAP_PROP_FRAME_WIDTH))    y_shape = int(player.get(cv2.CAP_PROP_FRAME_HEIGHT))    four_cc = cv2.VideoWriter_fourcc(*"MJPG") #Using MJPEG codex    out = cv2.VideoWriter(out_file, four_cc, 20, \                          (x_shape, y_shape))     ret, frame = player.read() # Read the first frame.    while rect: # Run until stream is out of frames        start_time = time() # We would like to measure the FPS.        results = self.score_frame(frame) # Score the Frame        frame = self.plot_boxes(results, frame) # Plot the boxes.        end_time = time()        fps = 1/np.round(end_time - start_time, 3) #Measure the FPS.        print(f"Frames Per Second : {fps}")        out.write(frame) # Write the frame onto the output.        ret, frame = player.read() # Read next frame.

你們應該將所有這些組件打包到一個類中,該類可以與你們希望將輸出流寫入其中的 URL 和輸出文件一起調用。最終效果如下:


十二、結論


當然,生產級實時應用程序比這複雜得多,但本文並不打算教授這一點。它是爲了展示 Python 的驚人力量,它使我們能夠在數小時內構建如此複雜的應用程序原型。


Github代碼鏈接:https://github.com/akash-agni


努力分享優質的計算機視覺相關內容,歡迎關注:

  
     
     
     
個人微信(如果沒有備註不拉羣!
請註明: 地區+學校/企業+研究方向+暱稱



下載1:何愷明頂會分享


AI算法與圖像處理」公衆號後臺回覆:何愷明,即可下載。總共有6份PDF,涉及 ResNet、Mask RCNN等經典工作的總結分析


下載2:終身受益的編程指南:Google編程風格指南


AI算法與圖像處理」公衆號後臺回覆:c++,即可下載。歷經十年考驗,最權威的編程規範!




   
   
   
下載3 CVPR2021

AI算法與圖像處公衆號後臺回覆: CVPR 即可下載1467篇CVPR 2020論文 和 CVPR 2021 最新論文

點亮 ,告訴大家你也在看


本文分享自微信公衆號 - AI算法與圖像處理(AI_study)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章