在學習物體識別前,我們先來認識下圖像識別。
圖像識別,簡單地來說,就是一個將圖像與特定的詞語對應起來的過程。從技術上來看,是利用電腦對圖像進行處理、分析和理解,以識別各種不同模式的目標和對象的過程。圖像識別的發展經歷了三個階段:文字識別、數字圖像處理與識別、物體識別。
文字識別的研究是從 1950年開始的,一般是識別字母、數字和符號,從印刷文字識別到手寫文字識別,應用非常廣泛。
數字圖像處理和識別的研究開始於1965年。數字圖像與模擬圖像相比具有存儲、傳輸方便可壓縮、傳輸過程中不易失真、處理方便等巨大優勢,這些都為圖像識別技術的發展提供了強大的動力。
物體識別主要指對三維世界的物體及環境的感知和認識,屬於高級的計算機視覺範疇。它是以數字圖像處理與識別為基礎的結合人工智能、系統學等學科的研究方向,其研究成果被廣泛應用在各種工業及機器人中。
瞭解了這些知識,我們再來看下面這四幅圖,第一張圖片是手寫數字,可以看到電腦將它正確地識別為了425,後三張圖片則分別分類為貓、人和車。
這就是文字識別和物體識別的一些應用,電腦可通過深度學習算法,對輸入的圖像進行識別,並給出每幅圖片的識別結果。
在人工智能領域,識別問題又可以歸類為分類問題,所以物體識別,也可以稱之為物體分類。
我們前面提到了,圖像識別就是電腦獲取,處理和分析圖像數據的過程,這個過程其實也就是計算機視覺的實現過程。簡而言之,計算機視覺使得電腦能夠“看”事物——甚至包括人類無法看到的事物。然而,要想讓電腦做到人類無法做到的事情,我們必須首先使電腦能夠做到人類可以做的事情:看到並標記物體和生物。這是圖像識別的主要功能。
我們先來看下下面這四幅貓的圖片,我們可以很輕鬆地分辨出這四張圖片都是貓,即使它們外形長相完全不同,且體態各異,即使它只露出了一截尾巴,但我們仍然可以分辨的出來。
但這對電腦來說卻十分困難,因為電腦並沒有像我們人類大腦這樣複雜的系統。
那麼,到底電腦是如何識別圖片的呢?我們來看下一節內容。
電腦想要正確分類圖片,就需要像我們人類一樣去學習,知道圖片中大量的資訊。目前,最有可能讓電腦實現“看”的能力的技術叫做深度學習(Deep Learning,簡稱DL),它是一種讓電腦從圖片中學習的方法。學習的過程稱為訓練,識別的過程稱為推理(測試)。
電腦要識別圖片,前提便是需要大量的圖片數據作為輸入,傳入電腦以供其學習。
我們以識別貓為例,前期需要先準備大量的各種品類的貓,並且打上標籤,告訴電腦:這些是貓,也就是這些圖片的分類,然後電腦將這些數據輸入網路,執行訓練,通過不斷地迭代進行學習,達到正確認識這些貓的目的。
然後,我們輸入電腦一張新的貓的圖片,進行測試,電腦執行測試演算法,便可給出輸入圖片的正確分類。
這個過程就是電腦“看”事物(學習),並給出答案(識別)的過程。
深度學習就是一種機器學習框架,通過模仿人類的神經元系統,為電腦提供自主學習能力。因此,電腦可以自動識別與發掘圖像數據的特徵,準確識別圖片中的內容,而無需根據指令或手動編碼來實現(但它需要大量的數據),並大大提高了計算精度及識別準確率。
而模仿人類神經元系統的方法,在人工智能領域被稱為神經網路(Neural Networks)。
下面,我們以圖像識別的入門級應用:MNIST手寫數字識別為例,來認識神經網路與深度學習的原理。其中,MNIST是一個手寫數字的圖片數據集。
手寫識別是常見的圖像識別任務。電腦通過手寫體圖片來識別出圖片中的字,與印刷字體不同的是,不同人的手寫體風格迥異,大小不一, 造成了電腦對手寫識別任務的一些困難。
在研究過程中,數字手寫體識別由於其有限的類別(0~9共10個數字)成為了相對簡單的手寫識別任務。所以,我們從簡單的手寫數字識別入手,來認識實現圖像識別的演算法。
前面已經提到,電腦需要像人一樣思考學習,才能識別出圖像,我們不妨反推一下,想一想我們小時候是怎樣學習數字的,大家總結回想一下,我們學習數字的思維過程。為什麼我們可以看到各式各樣形狀的數字,依舊可以知道它們分別是多少呢?
這個過程也就是電腦要模仿的,我們把這個學習步驟寫出來。
這個就是人類學習和認知的過程,也就是機器要模仿的,現在我們將人的學習方式類比到電腦中,就會知道電腦學習並識別數字的過程了。
我們向電腦輸入正確的帶有標籤的圖像數據,電腦看到的並不是像我們人類看到的那樣,如下圖左邊的圖片,而是下圖右邊數字矩陣的樣子。電腦中處理圖像,處理的是圖像中每一個像素(像素是電腦螢幕上所能顯示的最小單位,是用來表示圖像的單位)。
上一節我們提到了,深度學習需要大量的數據作為輸入,在手寫數字識別系統中,數據來自於MNIST數據集,它包含60000個訓練集和10000測試數據集。分為圖片和標籤,圖片是28*28的像素矩陣,標籤為0~9共10個數字。
有了數據集,下一步,便是將數據輸入到深度學習網路中,也就是神經網路中(這裏採用的是LeNet-5卷積神經網路模型,卷積神經網路是深度學習神經網路中最常見的一種),進行自動的特徵提取及學習,這個過程就是前面提到過的訓練過程。
我們知道,人類大腦的神經網路是由神經元和突觸組成,它們協同工作,完成對外界資訊的處理與傳遞。
那麼,人腦的神經網路對比到深度學習中,就是如下圖所示的網路。
大量的手寫數字圖像就是輸入數據,作為第一層:輸入層(一般情況下,輸入層不在網路結構中體現,而在後面訓練開始時給出),因為每張圖像的像素是28x28,所以每張圖像一共有784個像素,電腦中的索引一般從0開始,所以輸入x即為x0-x783。
中間部分稱為隱藏層,在LeNet-5網路中,主要採用的是:卷積層Convolutional Layer(啟動層為ReLu Layer)、池化層Pooling Layer以及全連接層Fully Connected Layer。
全連接層中加入啟動函數:Softmax,這是一個回歸模型,用於分類過程,可解決多分類問題。這裏的手寫數字識別就是一個多分類問題,0-9共10類,所以最後的輸出層y的結果為y0-y9。
並且Softmax也是一個概率函數,它可以給出輸入圖像識別為不同類別的概率,以此來讓使用者判斷輸入圖像中的數字更像哪一個識別結果。
這部分就是神經網路的網路結構,是深度學習演算法實現圖像處理及學習的根本。
前面我們給出了人類學習和認識數字的過程,也就是下圖左邊的部分,通過上一節的學習,我們知道了電腦學習並認識數字的過程,那麼總結起來,就是下圖右邊所示的步驟。
接下來,我們來學習今天最重要的部分——物體識別。
物體識別(Object Recognition)是計算機視覺中的一個應用,目的是讓電腦去分析一張圖片或者一段影片中的物體,並標注出其中物體所屬的類別。
YOLO是目前應用非常廣泛的一種物體識別演算法。YOLO的意思是You only look once,也就是你只看一眼,就能認出這是什麼物體,體現YOLO演算法識別的精度和速度。
YOLO是基於Pascal VOC2012數據集的目標檢測系統。它能夠檢測到20種Pascal的目標類別,包括:
在學習瞭解了深度學習與物體識別的原理之後,我們開始積木程式塊的學習,將理論與實踐相結合,才能更好地學習並認識物體識別。
<tr>
<td width="50%">積木</td>
<td width="20%">指令</td>
<td width="30%">說明</td>
</tr>
<td width="50%"><img src="./media/ai/AI_r1.png" width="300"/></td>
<td width="20%">載入模型</td>
<td width="30%">載入人工智能模型,可以從選單中選擇常用識別模型<img src="./media/ai/AI_r2.png" width="300"/></td>
<td width="50%"><img src="./media/ai/AI_r3.png" width="300"/></td>
<td width="20%">獲取識別結果</td>
<td width="30%">獲取當前結果,可選擇數字識別的結果或者識別為某個數字的置信度<img src="./media/ai/AI_r4.png" width="300"/></td>
<td width="50%"><img src="./media/ai/AI_r5.png" width="300"/></td>
<td width="20%">物體識別</td>
<td width="30%">獲取物體識別真假值,如果識別到物體會返回「真」值,否則返回「假」值</td>
<td width="50%"><img src="./media/ai/AI_r6.png" width="300"/></td>
<td width="20%">物體識別結果的參數</td>
<td width="30%">獲取識別到的每個物體的各項參數,包括:<img src="./media/ai/AI_r7.png" width="300"/></td>
<td width="50%"><img src="./media/ai/AI_r8.png" width="300"/></td>
<td width="20%">人臉識別</td>
<td width="30%">獲取人臉識別真假值,如果識別到人臉會返回「真」值,否則返回「假」值</td>
<td width="50%"><img src="./media/ai/AI_r9.png" width="300"/></td>
<td width="20%">人臉識別結果的參數</td>
<td width="30%">獲取識別到的每個人臉的各項參數,包括:<img src="./media/ai/AI_r10.png" width="300"/></td>
<td width="50%"><img src="./media/ai/AI_r11.png" width="300"/></td>
<td width="20%">加載客制化模型</td>
<td width="30%">從指定路徑加載用戶預訓練好的客制化模型:/sd/user/mymodel.kmodel
並根據要識別的物體種類來設定客制化物體的類別名稱:Object Name
<td width="50%"><img src="./media/ai/AI_r12.png" width="300"/></td>
<td width="20%">客制化的物體識別</td>
<td width="30%">獲取客制化物體識別真假值,如果識別到客制化物體會返回「真」值,否則返回「假」值</td>
<td width="50%"><img src="./media/ai/AI_r13.png" width="300"/></td>
<td width="20%">客制化物體識別結果的參數</td>
<td width="30%">獲取識別到的每個客制化物體的各項參數,包括:<img src="./media/ai/AI_r14.png" width="300"/></td>
在積木指令區點按以下指令,並依次放在積木編程區: 1. AI模組|圖像處理:【相機初始化】 2. 循環:【一直重複執行】 3. AI模組|AI模型:【加載預設模型】 選擇:模型:「常見物體檢測模型」 圖像:「img_objectrecognition」 4. 變數:【設定變數】img_objectrecognition 5. AI模組|相機:【獲取相機捕捉的圖像】 6. 邏輯:【邏輯判斷】 7. AI模組|模型:【識別到了任意常見物體】 8. 序列埠通訊|打印:【打印文字】 識別到物體則顯示「Object Detected」,否則「Nothing Detected」 |
|
注意:步驟4必須使用內建變數「img_objectrecognition」,所以首先要在步驟3使用「加載預設模型」指令,然後才進行步驟4及步驟5。 | |
測試結果:在「代碼區」點按「串口互動窗」,將模組向四周掃描,並觀察顯示的結果如下,當檢測到有物體時會顯示「Object Found」,否則會顯示「Nothing」 |
重複活動一的程式,在步驟8「顯示文字」指令修改如下: 1. 循環:【For循環】 2. AI模組|模型:【識別到了任意常見物體】 3. 序列埠通訊:【打印】 4. AI模組|模型:【獲取物體參數】選擇「物體名稱」 |
|
測試結果:點按「串口互動窗」,將模組向四周掃描,並觀察顯示的結果如下,當檢測到有物體時會顯示「物體名稱」,否則會顯示「Nothing」 |
在積木指令區點按以下指令,並依次放在積木編程區: 1. AI模組|螢幕:【初始化】 2. AI模組|相機:【初始化】 3. 循環:【重複執行】 |
在【重複執行】積木指令內,放置下列積木指令: 4. AI模組|AI模型:【加載模型】 (模型:常見物體識別模型 圖像:img_objectrecognition) 5. 變數:【賦值】(名稱:img_objectrecognition) 6. AI模組|相機:【獲取影像】 7. 變數:【建立變數】(名稱:img_display) 8. AI模組|圖像處理:【調整畫布尺寸】 9. AI模組|圖像處理:【圖像轉換】 |
|
在【圖像轉換】積木指令之後,放置下列積木指令: 10. 邏輯:【邏輯判斷】 11. AI模組|AI模型:【物體識別】 12. 循環:【For循環】 13. AI模組|AI模型:【物體識別】 14. AI模組|圖像處理:【螢幕文字】,並修改座標的X值及Y值,使「物體名稱」顯示在螢幕左上角的適宜位置 15. 文字:【建立字串使用】 16. AI模組|模型:【獲取物體參數】選擇「物體名稱」 17. AI模組|圖像處理:【螢幕文字】並輸入「Nothing Detected.」,並修改座標的X值及Y值 |
|
在步驟10【邏輯判斷】積木指令之後,放置下列積木指令: 18. AI模組|螢幕:【設定起始點坐標】、【顯示畫布】(名稱:img_display 起始座標X:8 Y值:36) |
|
將上面專題中的第三步改為以下內容:在螢幕中顯示識別到的物體位置並以檢測框的形式標註出來。
在【圖像轉換】積木指令之後,放置下列積木指令: |
在步驟10【邏輯判斷】積木指令之後,放置下列積木指令: 19. AI模組|螢幕:【顯示畫布】(名稱:img_display 起始座標X:8 Y值:36) |
完整Python代碼: |
完整程式: |
運行結果: |