1.1. 項目簡介
目標檢測(Object Detection)的任務是在圖像中找出檢測對象的位置和犬小,是計算機視覺領域的核心問題之一,在自動駕駛、機器人和無人機等許多領域極具研究價值。
隨着深度學習的興起,基於深度學習的目標檢測算法逐漸成爲主流。深度學習是指在多層神經網絡上運用各種機器學習算法決圖像、文本等各種問題的算法集合。因此,基於深度學習的目標檢測算法又披稱爲目標檢測網絡。
本項目使用一種名爲 MobileNet-SSD的目標檢測網絡對圖像進行目標撿測。
MobileNet-SSD 能夠在圖像中檢測出飛機、自行車、鳥、船、瓶子、公交車、汽車、貓、椅子、奶牛、餐桌、狗、馬、摩托車、人、盆栽、羊、沙發、火車和電視機共 20 種物體和 1 種背景,平均準確率能達到72. 7%。由於訓練神經網絡需要大量的數據和強大的算力,這裏將使用一個已經訓練好的目
標檢測網絡模型。在 Python 中,可以通過OpenCV 的dnn模塊使用訓練好的模型對圖像進行目標檢測,其步驟如下。
(1) 加載 MobileNet_SSD目標檢測網絡模型。
(2) 讀入待檢測圖像,並將其轉換成 blob 數據包。
(3) 將 blob 數據包傳入目標檢測網絡,並進行前向傳播。
(4) 根據返回結果標註圖像中被檢測出的對象。
1.2. 準備工作
在磁盤上創建一個名爲“object-detect”的文件夾作項目目錄,用於存放本項目的模型、源程序、圖像和視頻等文件,然後從原書“資源包/第 34 課”文件夾中把 model、images 和 videos3 個文件夾複製到“object-detect”文件夾中。
在model文件夾中提供 MobileNetSSD目標撿測網絡模型文件,包括神經網絡模型文件 MobileNetSSD_deploy.caffemodel 和網絡結構 描述文件MobileNetSSD_deploy.prdtotxt。
在images文件夾中提供一些用於進行目標檢測的圖像,這些圖像裏含有汽車、飛機、行人、馬、貓等。
1.3. 目標檢測過程
新建一個空白源文件,以object_detection.jl作爲文件名保存至“object-detect”文件夾中,然後編寫程序檢測圖像中的物體,具體過程如下。
(1) 導入cv2和其他模塊
using PyCall using Printf using Distributions cv2=pyimport("cv2")
說明:Printf庫主要用於字符串的格式化輸出。Distributions庫是用於概率分佈和相關函數的Julia包,這裏用於配合隨機數發生器,生成一定分佈範圍的隨機數。Distributions庫需要安裝。
(2) 創建表示圖像文件、網絡描述文件和網絡模型文件等的變量。
#指定圖像和模型文件路徑 image_path = "./images/example_1.jpg" prototxt = "./model/MobileNetSSD_deploy.prototxt" model = "./model/MobileNetSSD_deploy.caffemodel"
(3) 創建物體分類標籤、顏色和字體等的變量。
#設定目標名稱 CLASSES = ("background", "aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "dining-table", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor") COLORS =rand(Uniform(0, 255),length(CLASSES),3)# FONT = cv2.FONT_HERSHEY_SIMPLEX
CLASSES 變量中這些分類標籤是通過 MobileNet-SSD 網絡訓練的能夠被檢測的物體的名稱,包括20種物體和1種背景。
COLORS 變量存放的是隨機分配的標籤顏色。這裏原python代碼是這樣的:
COLORS =numpy.random.uniform(0, 255, size=(len(CLASSES), 3))
對於Julia,我們安裝了Distributions庫,就可以配合rand函數生成0-255範圍內的隨機數。
(4) 使用dnn模塊從文件中加載神經網絡模型。
#加載網絡模型
net = cv2.dnn.readNetFromCaffe(prototxt, model)
(5) 從文件中加載待檢測的圖像,用來構造一個 blob 數據包。
#讀取圖像並進行預處理 image = cv2.imread(image_path) (h, w) = size(image)[1:2] input_img = cv2.resize(image, (300, 300)) blob = cv2.dnn.blobFromImage(input_img, 0.007843, (300, 300), 127.5 rimg = permutedims(image, ndims(image):-1:1) pyimg = PyReverseDims(rimg)
cv2.dnn.blobFromImage函數返回一個blob 數據包,它是經過均值減法、歸一化和通道交換之後的輸人圖。由於訓練 MobileNet-SSD 網絡時使用的是 300 * 300 大小的圖像,所以這裏也需要使用相同尺寸的圖像。
(6) 將 blob 數據包傳人 MobileNet-SSD目標檢測網絡,並進行前向傳播,然後等待返回檢測結果。
#將圖像傳入網絡
net.setInput(blob)
detections = net.forward()
(7) 用循環結構讀取檢測結果中的檢測區域,並標註出矩形框、分類名稱和可信度。
#對結果進行處理 for i in 1:size(detections)[3] idx =floor(Int,detections[1, 1, i, 2]) confidence = detections[1, 1, i, 3] if confidence > 0.2 #畫矩形框 #println(size(detections)) box = detections[1, 1, i, 4:7].* [w, h, w, h] (x1, y1, x2, y2) = floor.(Int,box)#.astype("int") #println(idx) cv2.rectangle(pyimg, (x1, y1), (x2, y2), COL-ORS[idx], 2) #標註信任度 label =label=@sprintf("[INFO] %s: %0.2f%%",CLASSES[idx], confidence * 100) #print(label) cv2.putText(pyimg, label, (x1, y1), FONT, 1, COLORS[idx], 1) end end
(8) 將檢測結果圖像顯示在窗口中。
#顯示圖像並等待 cv2.imshow("Image", pyimg) cv2.waitKey(0) cv2.destroyAllWindows()
至此 目標檢測程序編寫完畢。運程程序,對圖像(example_1.jpg)的檢測結果如圖所示: