在 Vultr 雲服務器中使用 Tensorflow 進行對象檢測

介紹

對象檢測是一種計算機視覺技術,可以在數字圖像或視頻中識別/定位某一類對象的實例,例如人、建築物或車輛。 目標檢測可用於各種計算機視覺任務,包括圖像註釋、人臉檢測、目標跟踪、活動識別和車輛計數。

Tensorflow 是一個綜合性的開源平台,用於構建基於機器學習的應用程序。 它包含豐富的工具和庫,主要專注於神經網絡訓練和推理。

本指南使用 Tensorflow 創建對象檢測應用程序。

以前的要求

您將需要以下內容:

物體檢測的工作原理

對象檢測通常通過生成輸入圖像的小片段來完成,特徵提取用於驗證該片段是否是有效對象,並將重疊的片段框組合成單個邊界矩形。

目標檢測通常有兩種方法:非神經和基於神經網絡的方法。 非神經方法包括:

  • Viola-Jones 對象檢測框架– 它建立在 Haar 的特徵之上,這些特徵最初是為人臉檢測而提出的,但可以擴展到其他物體檢測。 通過計算兩個相鄰矩形區域的像素強度並求和之間的差異,可以捕獲圖像部分的特徵。

  • 定向梯度的直方圖函數 (HOG)– 此方法是一個函數描述符,用於計算圖像局部部分中梯度方向的出現次數。 HOG特徵描述符不僅關注物體的結構或形狀,還可以提供邊緣的方向。 在局部部分計算梯度方向,將圖像劃分為更小的區域,並為每個區域計算梯度和方向。 這種方法適用於行人檢測。

  • 尺度不變特徵變換 (SIFT)– 包括檢測圖像中的關鍵點(局部特徵)。 從參考圖像中提取一組關鍵對象點並存儲在數據庫中; 通過將新圖像的特徵與數據庫單獨比較來識別新圖像中的對象。 基於與其特徵向量的歐氏距離找到匹配特徵。 SIFT 有一個額外的優勢,它不受圖像大小或方向的影響。

基於神經網絡的對象檢測通常涉及從頭開始設計和訓練神經網絡架構,或者利用已經使用自定義數據集在大型數據集上訓練過的預訓練網絡(稱為遷移學習)。 遷移學習是一種重用從解決問題中獲得的先驗知識並將相同知識應用於單獨但相關的問題的方法。 神經網絡方法包括:

  • 你只看一次(YOLO)– 是最先進的實時對象檢測系統,通過將單個神經網絡應用於完整圖像來工作。 神經網絡將圖像劃分為單獨的區域,並預測每個區域的邊界框和概率。 邊界框由預測概率加權。 YOLO 非常快,因為它只遍歷圖像一次。

  • 基於區域的捲積神經網絡 (R-CNN)– 使用區域建議通過選擇性搜索算法在圖像中定位對象。 CNN 提取特徵,輸出密集層由從圖像中提取的特徵組成,饋送到 SVM 以對特定提議區域內對象的存在進行分類。 R-CNN 是一系列算法,包括 R-CNN、Fast R-CNN 和 Fastest R-CNN。

  • 視網膜網絡– 是一種單階段目標檢測模型,它使用焦點損失函數來解決訓練期間的類不平衡問題。 RetinaNet 是一個單一的統一網絡,由負責計算整個輸入圖像上的捲積特徵圖的主乾和兩個特定於任務的子網組成。 第一個子網對主幹的輸出執行卷積對象分類。 第二個子網執行卷積邊界框回歸。

基於神經網絡的目標檢測在現代場景中更為普遍,因為它可以產生更好的結果並且更先進。

項目虛擬環境的配置

為應用程序創建一個隔離的虛擬環境:

  1. 安裝 virtualenv 蟒蛇包:

                              
                                $ pip install virtualenv
    
                              
                            
  2. 創建項目目錄:

                              
                                $ mkdir obj_detection
    
                              
                            
  3. 導航到新目錄:

                              
                                $ cd obj_detection
    
                              
                            
  4. 創建虛擬環境:

                              
                                $ python3 -m venv env
    
                              
                            

    這將創建一個名為 env 包含控制虛擬環境的腳本,包括程序庫。

  5. 激活虛擬環境:

                              
                                $ source env/bin/activate
    
                              
                            

安裝張量流

要安裝 TensorFlow,請輸入以下命令:

                      
                        $ pip install tensorflow

                      
                    

TensorFlow 對象檢測 API

TensorFlow 對象檢測 API 是一個開源框架,可以輕鬆構建、訓練和部署基於 TensorFlow 的對象檢測模型。 它在其框架中包含一組預訓練模型,稱為 Model Zoo。 這些預訓練模型在各種數據集上進行訓練,包括:

  • 上下文中的常見對象 (COCO)– 是一個具有大量特徵的大規模對象檢測、字幕和分割數據集,包括上下文識別、150 萬個對象實例和超過 220,000 個標記圖像。

  • 卡爾斯魯厄理工學院和豐田技術學院 (KIITI)– 是用於自動駕駛和移動機器人的數據集。

本指南使用在 COCO 數據集上訓練的預訓練模型。

安裝 TensorFlow 對象檢測 API

要安裝 TensorFlow 對象檢測 API,請在項目目錄中克隆存儲庫:

                      
                        $ git clone https://github.com/tensorflow/models

                      
                    

項目目錄必須有一個楷模裡面的目錄。 導航到研究目錄:

                      
                        $ cd models/research

                      
                    

TensorFlow 對象檢測 API 使用 Protobufs 配置模型和訓練參數。 使用協議命令:

                      
                        $ protoc object_detection/protos/*.proto --python_out=.

                      
                    

安裝 COCO API

pycocotools 該包是 COCO 數據集的官方 API,是 TensorFlow 對象檢測 API 的依賴項。 要安裝,導航回項目目錄:

                      
                        $ cd ../..

                      
                    

克隆可可皮存儲庫:

                      
                        $ git clone https://github.com/cocodataset/cocoapi.git

                      
                    

更改目錄:

                      
                        $ cd cocoapi/PythonAPI

                      
                    

跑過構建庫的命令:

                      
                        $ make

                      
                    

構建成功後,複製pycocotools中的子文件夾調查TensorFlow 對象檢測 API 克隆存儲庫文件夾:

                      
                        $ cp -r pycocotools ../../models/research

                      
                    

安裝對象檢測 API

要安裝對象檢測 API,請在模型/研究文件:

                      
                        $ cp object_detection/packages/tf2/setup.py . && python -m pip install .

                      
                    

這將安裝項目的所有依賴項。

物體檢測器的構造

本指南使用在 COCO 數據集上訓練的預訓練對象檢測模型。 首先,創建 main.py 項目目錄中的文件:

                      
                        $ touch main.py

                      
                    

導入庫

通過添加以下行導入所需的庫:

                      
                        import tensorflow as tf

import numpy as np

from PIL import Image

from object_detection.utils import label_map_util

from object_detection.utils import visualization_utils as viz_utils

                      
                    

Numpy 用於算術和矩陣計算,而 Image pillow 庫類用於圖像處理。 從中導入的類對象檢測具有以下功能:

  • label_map_util :用於加載繪圖的標籤圖。 標籤映射將索引號映射到類別名稱,如果對象檢測的索引為 1,則將檢測映射為人。

  • visualization_utils :包含將標記框覆蓋在檢測到的對象之上的功能。

下載模型

可以立即下載並使用在 COCO 數據集上預訓練的幾個模型,如模型庫. 在本指南中,使用的預訓練模型是SSD ResNet152 V1 FPN 1024×1024 (RetinaNet152).

創建模型下載函數:

                      
                        def download_model(model_name, model_date):

    base_url="https://download.tensorflow.org/models/object_detection/tf2/"

    model_file = model_name + '.tar.gz'

    model_dir = tf.keras.utils.get_file(fname=model_name,

                                        origin=base_url + model_date + "https://www.vultr.com/" + model_file,

                                        untar=True)

    return str(model_dir)

                      
                    

此函數以模型名稱和模型日期為參數,並使用下載指定模型 get_file 張量流函數。 以字符串形式返回下載模型的目錄。

使用函數,下載給定的模型:

                      
                        # Download model

model_name = "ssd_resnet152_v1_fpn_1024x1024_coco17_tpu-8"

model_date = "20200711"

PATH_TO_MODEL_DIR = download_model(model_name, model_date)

                      
                    

這將下載傳遞的模型並將模型路徑保存在變量中。 要加載模型以在應用程序中使用,請添加以下行:

                      
                        # Load model

model_fn = tf.saved_model.load(PATH_TO_MODEL_DIR + "/saved_model")

                      
                    

load 該函數加載一個 SavedModel 作為參數傳遞的目錄。 這將返回一個帶有公司從簽名鍵到函數的屬性映射。 該對象可以作為圖像上的函數調用以進行對象推理。 這裡的已保存模型下載模型中的目錄作為參數傳遞。

上傳標籤

如上所述,標籤映射將索引號映射到類別名稱。 當檢測到的對象返回索引號時,標籤映射對該對象進行分類。 例如,檢測到的索引為 1 的對像被歸類為人。

要加載用於將索引號映射到類別名稱的標籤映射,請添加以下行:

                      
                        # Load labels

PATH_TO_LABELS = 'models/research/object_detection/data/mscoco_label_map.pbtxt'

category_index = label_map_util.create_category_index_from_labelmap(PATH_TO_LABELS, use_display_name=True)

                      
                    

標記映射文件的路徑保存在一個變量中並傳遞給 create _category_index_from_labelmap 功能。 此函數讀取標籤映射並返回包含代表所有可能類別的字典的類別列表。

上傳圖片

本指南使用以下圖像:

下載圖片,保存為 image1.jpg image2.jpg 分別,然後將它們放在項目目錄中。 項目目錄應如下所示:

                      
                        .

├── env/

└── models/

└── cocoapi/

└── main.py

└── image1.jpg

└── image2.jpg

                      
                    

將以下行添加到主程序程序:

                      
                        # Images to run detection

images = ["image1.jpg", "image2.jpg"]



for image in images:

    print(f"Running inference for image - {image}")



    # Load image into a numpy array

    image_np = np.array(Image.open(image))



    # Convert image to tensor

    input_tensor = tf.convert_to_tensor(image_np)



    # Add an axis

    input_tensor = input_tensor[tf.newaxis, ...]

                      
                    

使用圖片.open函數,打開圖像並使用訓練麻木的功能。 對象檢測器將張量作為輸入,因此必須使用 convert_to_tensor 功能。 由於模型需要一批圖像,因此還添加了一個新軸。

運行推理

要從圖像中推斷對象,請添加以下行:

                      
                            # Run inference

    detections = model_fn(input_tensor)

                      
                    

該模型以輸入張量作為參數調用,這會在模型中運行張量,並通過將輸出作為標記檢測對象邊界的張量批返回來執行檢測。

                      
                            # Outputs are tensor batches.

    # Convert to numpy arrays, and take index [0] to remove the batch dimension.

    num_detections = int(detections.pop('num_detections'))

    detections = {key: value[0, :num_detections].numpy()

                  for key, value in detections.items()}

    detections['num_detections'] = num_detections



    # detection_classes cast as ints.

    detections['detection_classes'] = detections['detection_classes'].astype(np.int64)

                      
                    

上面幾行將張量批次轉換為 numpy 數組,刪除不需要的批次維度,並在清理後更新檢測次數。 然後將檢測類別從其浮點表示形式轉換為整數。

查看檢測

要在圖像中檢測到的對象周圍繪製框,請添加以下行:

                      
                            image_np_with_detections = image_np.copy()



    viz_utils.visualize_boxes_and_labels_on_image_array(

            image_np_with_detections,

            detections['detection_boxes'],

            detections['detection_classes'],

            detections['detection_scores'],

            category_index,

            use_normalized_coordinates=True,

            max_boxes_to_draw=200,

            min_score_thresh=.30,

            agnostic_mode=False,

            line_thickness=8)

                      
                    

圖像的副本是使用複製方法,以及 visualize_boxes_and_labels_on_image_array 功能:用格式化標籤的名稱和分數覆蓋圖像上的標籤框。 需要 5 個參數:

  • 圖像– 要與幀疊加的圖像作為 numpy uint8 數組。

  • 盒子– 一個形狀為 [N, 4] 的 numpy 數組。

  • 班級– 一個形狀為 [N] 的 numpy 數組。 類索引與標籤映射中的鍵匹配,並且從 1 開始。

  • 分數– 種類繁多的形狀 [N] 或無。 如果設置為 None,該函數假定要繪製的框為真,並且還將沒有類或分數的框繪製為黑色。

  • 類別索引– 包含由索引 ID 和類別名稱組成的類別字典的字典,由索引編碼。

必需的參數與其他可選參數一起傳遞。 在這個使用可選參數的示例中,要繪製的最大框數設置為 200,線條粗細設置為 8。

保存帶有檢測的圖像

要保存帶有表示檢測的疊加框的圖像,請添加以下行:

                      
                            # Save image with detections

    img = Image.fromarray(image_np_with_detections)

    img_filename = image[0:-4] + "_detect" + image[-4:]

    img.save(img_filename)

                      
                    

新圖像保存為_探測添加到其原始名稱。

最終代碼

僅供參考,完整代碼:

                      
                        import tensorflow as tf

import numpy as np

from PIL import Image

from object_detection.utils import label_map_util

from object_detection.utils import visualization_utils as viz_utils



def download_model(model_name, model_date):

    base_url="https://download.tensorflow.org/models/object_detection/tf2/"

    model_file = model_name + '.tar.gz'

    model_dir = tf.keras.utils.get_file(fname=model_name,

                                        origin=base_url + model_date + "https://www.vultr.com/" + model_file,

                                        untar=True)

    return str(model_dir)



# Download model

model_name = "ssd_resnet152_v1_fpn_1024x1024_coco17_tpu-8"

model_date = "20200711"

PATH_TO_MODEL_DIR = download_model(model_name, model_date)



# Load model

model_fn = tf.saved_model.load(PATH_TO_MODEL_DIR + "/saved_model")



# Load labels

PATH_TO_LABELS = 'models/research/object_detection/data/mscoco_label_map.pbtxt'

category_index = label_map_util.create_category_index_from_labelmap(PATH_TO_LABELS, use_display_name=True)



# Images to run detection

images = ["image1.jpg", "image2.jpg"]



for image in images:

    print(f"Running inference for image - {image}")



    # Load image into a numpy array

    image_np = np.array(Image.open(image))



    # Convert image to tensor

    input_tensor = tf.convert_to_tensor(image_np)



    # Add an axis

    input_tensor = input_tensor[tf.newaxis, ...]



    # Run inference

    detections = model_fn(input_tensor)



    # Outputs are tensor batches.

    # Convert to numpy arrays, and take index [0] to remove the batch dimension.

    num_detections = int(detections.pop('num_detections'))

    detections = {key: value[0, :num_detections].numpy()

                  for key, value in detections.items()}

    detections['num_detections'] = num_detections



    # detection_classes cast as ints.

    detections['detection_classes'] = detections['detection_classes'].astype(np.int64)



    image_np_with_detections = image_np.copy()



    viz_utils.visualize_boxes_and_labels_on_image_array(

            image_np_with_detections,

            detections['detection_boxes'],

            detections['detection_classes'],

            detections['detection_scores'],

            category_index,

            use_normalized_coordinates=True,

            max_boxes_to_draw=200,

            min_score_thresh=.30,

            agnostic_mode=False,

            line_thickness=8)



    # Save image with detections

    img = Image.fromarray(image_np_with_detections)

    img_filename = image[0:-4] + "_detect" + image[-4:]

    img.save(img_filename)

                      
                    

運行代碼

要運行代碼,請從項目目錄中輸入以下命令:

                      
                        $ python main.py

                      
                    

生產:

                      
                        Downloading data from https://download.tensorflow.org/models/object_detection/tf2/20200711/ssd_resnet152_v1_fpn_1024x

1024_coco17_tpu-8.tar.gz

504180168/504180168 [==============================] - 133s 0us/step



Running inference for image - image1.jpg

Running inference for image - image2.jpg

                      
                    

該代碼成功下載了模型並從圖像中推斷出對象。 在項目目錄中,存在對象檢測到的已保存圖像:

                      
                        .

├── env/

└── models/

└── cocoapi/

└── main.py

└── image1.jpg

└── image1_detect.jpg

└── image2.jpg

└── image2_detect.jpg

                      
                    

打開新圖像:

Foto de playa de personas y objetos detectados.

Foto de 3 perros detectados

在第一張圖片中,物體檢測器正確標記了所有物體,而在第二張圖片中,它識別出 3 只動物,但由於特徵驚人相似,將中間的狗分類為熊。

結論

本指南涵蓋對象檢測以及如何在 TensorFlow 中構建對象檢測器。

文章標題 名稱(可選) 電子郵件(可選) 描述

發送建議

相關文章