本文說明如何使用 LattePanda搭配OpenCV視覺辨識函式庫來打造人臉辨識機器人。
| 作者/攝影 | 袁佑緣 |
| 時間 | 1小時 |
| 難度 |
★★☆☆☆ |
| 材料表 |
|
本文說明如何使用 LattePanda搭配 python語言去使用OpenCV機器視覺函式庫來打造一個人臉辨識機器人,本範例的操作環境將以LattePanda的Windows10為主。
1. 軟體準備
安裝Python與相關套件
首先請到Python的網站下載最新版的安裝檔,在這邊要提醒一下Python目前有兩種版本,一個是2.7x版,另一個3.x版。Python 2.7x版是比較舊的版本,同時官方也有發出聲明將不會在繼續更新了,而本篇的範例使用的是新版3.x的Python,所以請注意一下不要選錯囉,以本文為例,最新的版本是3.6.1,如下圖。接著請按照以下步驟進行。
請在安裝Python時,將下方「Add Python 3.6 to PATH」勾選起來,意思是要把Python加入windows作業系統的環境變數內。
安裝完成後,為了測試我們的電腦是否能正常呼叫Python,請呼叫您電腦的終端機,windows的使用者請按下快捷鍵「win+R」便會在左下角顯示執行視窗,接著輸入「cmd」,這樣一來就會叫出windows的命令提示字元。
接下來請在上面輸入「Python」,呼叫Python的互動界面,如果能成功看到「>>>」的符號,那就代表已經成功叫起Python的界面了,而使用者可以直接在上面輸入Python的相關指令,如果沒有正確顯示這個界面的話,可能是您前面的安裝過程有問題,請重新回到前面的安裝步驟,有可能是您沒有勾選系統變數那個選項,所以windows無從呼叫Python。
接下來請輸入「exit()」跳出這個Python互動界面,回到windows的命令提示字元。
接下來請輸入「pip install numpy」,使用Python的套件管理員pip來安裝numpy這個套件。
裝完numpy之後,一樣使用pip來安裝OpenCV套件,請輸入「pip install opencv-python」。
最後請輸入「pip install pyserial」,安裝在python中用來做Serial溝通的pyserial套件。
準備Python IDE
撰寫Python的程式除了要打code之外,還需要執行的環境,所以筆者在這邊推薦一款非常容易上手的Python IDE,請到以下的網站(http://thonny.org/)下載並安裝Thonny。
裝完必要的Python套件之後,我們就要來把Thonny的程式路徑設定成我們電腦系統中預設的Python執行程式。請點選Tools然後再點選Options,進入Thonny的偏好設定。如下圖。
接下來選擇interpreter,也就是Python的直譯器為系統預設的路徑,如下圖。
2.硬體架設
本範例使用羅技C170的webcam作為辨識人臉的攝影鏡頭,另外為了要能夠追蹤人臉的位置,我們還需要架設一個旋轉平台,如下圖,由底下的小型伺服馬達(MG90)來控制鏡頭對到的方位。且注意到下方的小馬達控制訊號線是接到LattePanda左邊的3Pin接頭,記得靠外側是要接深色的地線喔!
3.軟體實作
Arduino 程式碼
為了要控制旋轉平台的伺服馬達,我們需要使用LattePanda上的Arduino Leonardo晶片,請打開Arduino IDE並打上以下的程式碼,並上傳到LattePanda上的Arduino端(請記得選對COM port)。
Arduino端的控制動作其實很簡單,它會聽取Serial傳來的字元命令,如果是小寫的字母a或b就會分別左右旋轉一度,進而達到轉動鏡頭的效果,而伺服馬達的控制訊號腳位在本範例中用的是9號腳位,接法如上圖,如果想接其他腳位請記得要改一下Arduino程式碼裡的腳位定義(s.attach(9))。
[pastacode lang=”java” manual=”%23include%20%3CServo.h%3E%0A%0AServo%20s%3B%0Aint%20degree%20%3D%2090%3B%0A%0Avoid%20setup()%0A%7B%0A%20%20%20%20Serial.begin(115200)%3B%0A%20%20%20%20s.attach(9)%3B%0A%7D%0A%0Avoid%20loop()%0A%7B%0A%20%20%20%20if(Serial.available())%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20int%20cmd%20%3D%20Serial.read()%3B%0A%20%20%20%20%20%20%20%20if(cmd%20%3D%3D%20’a’)%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20degree%2B%2B%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(degree%20%3E%3D%20180)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20degree%20%3D%20180%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20s.write(degree)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20else%20if(cmd%20%3D%3D%20’b’)%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20degree–%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(degree%20%3C%3D%200)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20degree%20%3D%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20s.write(degree)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20else%0A%20%20%20%20%20%20%20%20%20%20%20%20Serial.println(%22Press%20a%2Fb%20to%20turn%20the%20camrea!%22)%3B%0A%20%20%20%20%7D%0A%7D%0A” message=”” highlight=”” provider=”manual”/]
Python 程式碼
前面已經準備好Python會需要用到的函式庫跟IDE了,接下來我們就要來實作最後關鍵的人臉辨識以及追蹤,因為需要用到辨識人臉的模型,請去OpenCV的github網站(https://github.com/opencv/opencv/tree/master/data/haarcascades)下載 haarcascade_frontalface_default.xml與 haarcascade_eye.xml這兩個.xml檔,分別是用來辨識人的臉部與以及眼睛。
程式碼的實做可以拆解成幾個重要的部份,以下就讓我們一步一步的來了解吧!
首先我們會由cv2.VideoCapture(0)來讀取Webcam的影像資訊,並且設定初始的解析度是640×480,接下來在連接埠COM5建立一個Serial通道,用來下指令給Arduino端,以控制鏡頭的方向。
而while迴圈裡面則包含了主要的辨識程式,辨識的方法其實很簡單,就是先把鏡頭每一幀的照片先灰階化,再透過前面下載的臉部及眼部辨識模組套進去(face_cascde和eye_cascade)去做最可能的人臉偵測(這裡使用的方法是取最大/近的臉部面積)。
最後為了要追蹤人臉,我們需要計算出人臉的中心位置(position = x + w/2.0),x是標示人臉方框的 角落x座標,w則是寬度,所以取一半的寬度就會得到人中的x座標位置,接下來我們只要跟我們取的影像中線做比較,然後左右旋轉鏡頭去做追蹤即可,而這調中線的位置則可以從前面設定的解析度640×480來算出,取寬的一半就能得到範例程式中的320了,如果說讀者想要嘗試其他的解析度,請記得也要修改鏡頭追蹤的中線喔!
[pastacode lang=”java” manual=”import%20cv2%0Aimport%20numpy%20as%20np%0Aimport%20serial%0A%0Aface_cascade%20%3D%20cv2.CascadeClassifier(‘.%2Fhaarcascade_frontalface_default.xml’)%0Aeye_cascade%20%3D%20cv2.CascadeClassifier(‘.%2Fhaarcascade_eye.xml’)%0A%0Acap%20%3D%20cv2.VideoCapture(0)%0Acap.set(3%2C%20640)%0Acap.set(4%2C%20480)%0Aser%20%3D%20serial.Serial(‘COM5’%2C%20115200)%0A%0Awhile%20True%3A%0A%20%20%20%20_%2C%20img%20%3D%20cap.read()%0A%20%20%20%20gray%20%3D%20cv2.cvtColor(img%2C%20cv2.COLOR_BGR2GRAY)%0A%20%20%20%20faces%20%3D%20face_cascade.detectMultiScale(gray%2C%202%2C%205)%0A%20%20%20%20if%20len(faces)%3A%0A%20%20%20%20%20%20%20%20(x%2C%20y%2C%20w%2C%20h)%20%3D%20max(faces%2C%20key%3Dlambda%20face%3A%20face%5B2%5D*face%5B3%5D)%0A%20%20%20%20%20%20%20%20cv2.rectangle(img%2C(x%2Cy)%2C(x%2Bw%2Cy%2Bh)%2C(255%2C0%2C0)%2C2)%0A%20%20%20%20%20%20%20%20roi_gray%20%3D%20gray%5By%3Ay%2Bh%2C%20x%3Ax%2Bw%5D%0A%20%20%20%20%20%20%20%20roi_color%20%3D%20img%5By%3Ay%2Bh%2C%20x%3Ax%2Bw%5D%0A%20%20%20%20%20%20%20%20eyes%20%3D%20eye_cascade.detectMultiScale(roi_gray)%0A%20%20%20%20%20%20%20%20for%20(ex%2Cey%2Cew%2Ceh)%20in%20eyes%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20cv2.rectangle(roi_color%2C(ex%2Cey)%2C(ex%2Bew%2Cey%2Beh)%2C(0%2C255%2C0)%2C2)%0A%20%20%20%20%20%20%20%20position%20%3D%20x%20%2B%20w%2F2.0%0A%20%20%20%20%20%20%20%20print(position)%0A%20%20%20%20%20%20%20%20if%20position%20%3C%20320%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20ser.write(b’a’)%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20ser.write(b’b’)%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20cv2.imshow(‘face’%2C%20img)%0A%20%20%20%20k%20%3D%20cv2.waitKey(5)%20%26%200xFF%0A%20%20%20%20if%20k%20%3D%3D%2027%3A%0A%20%20%20%20%20%20%20%20break%0Acv2.destroyAllWindows()%0A” message=”” highlight=”” provider=”manual”/]
示範影片
相關文章:



















Traceback (most recent call last):
File “C:\Users\User\Desktop\test.py”, line 16, in
faces = face_cascade.detectMultiScale(gray, 2, 5)
error: OpenCV(4.1.0) C:\projects\opencv-python\opencv\modules\objdetect\src\cascadedetect.cpp:1658: error: (-215:Assertion failed) !empty() in function ‘cv::CascadeClassifier::detectMultiScale’
請問我該如何解決此問題,謝謝
您好,請問有下載所需的 xml 檔? https://github.com/opencv/opencv/tree/master/data/haarcascades
那如果單純使用樹莓派 + 攝影機
要怎麼撰寫程式呢?
抱歉還有加上馬達 ,來達成人臉追蹤
您好,只用 pi 的話,要透過 PCA9685 來驅動 servo,請參考 https://www.robotkingdom.com.tw/product/pca9685/
請問一下
假如當我把辨識拿掉
要如何讓機械不要轉回原點
就停在原點就不要動
faces = face_cascade.detectMultiScale(gray, 2, 5) -> 去檢查如果 faces 為空的話,就停留在前一個時間的XY座標,這樣應該ok
你好 板子可以使用arduino uno嗎
您好,lattepanda 板載有一個 arduino 晶片,本篇文章是運用這個晶片來實作。如果您是要問 arduino uno 可否執行視覺辨識,技術上來說是不行的,要搭配其他的視覺處理硬體才能做到