使用舵機雲台追蹤臉孔

舵機雲台由兩個伺服馬達及一個組合式雲台構成,能夠同時進行左右及前後運動,我們使用的材料如下:

組合式舵機雲台 $50   http://goods.ruten.com.tw/item/show?21616553900468

SG90伺服馬達 $50 x2  http://goods.ruten.com.tw/item/show?21615514448168

組合起來就像這樣子:

「SG90舵機雲台」的圖片搜尋結果

接著把相機固定在雲台位置,硬體安裝就完成了,接下來是接線部份。

連接樹莓派

舵機雲台當中負責左右旋轉servo稱為Pan,上下轉動的稱為Tilt,它們的訊號線分別接到樹莓派的第7與11腳位。我們要注意的是電流的問題,樹莓派每個接腳輸出最大僅為16mA,全部接腳同時最大輸出也只能到50mA而已,但舵機SG90 servo的耗電量約在220-650 mA之間,因此無法直接使用樹莓派GPIO的5V電源,必須另外從外部取用,我的作法是從兩個樹莓派USB port取電,每個USB 2.0理論上可提供5V 500mA的電流,這對我們的servo來說是足夠的。

除了使用於舵機的兩台servo之外,我們另外加上一個PIR和LED。PIR用於偵測外界的動靜,當有人時才開啟舵機雲台進行搜尋,LED則作為指示器,當舵機雲台發現臉孔並鎖定時發出亮光。

人臉辨識

硬體和接線都完成後,接下來是軟體的部份。我們在安裝Opencv之後,於 /haarcascades目錄下會發現一些如下的xml 檔案:

這些檔案依其字面來看,有正面人臉、眼睛、載著眼鏡、嘴巴、鼻子、微笑、上半身、全身、由上往下的身體、甚至於還有貓臉…等等的xml檔案名稱,其實這每一個xml檔案這些都是opencv已訓練好的各種Harcascades分類器,我們可立即拿來使用於物體偵測而不需要自行花時間去訓練。

什麼是Haarcascades

Haarcascades是「Haar Feature-based Cascade Classifier」的縮寫,可分成Haar Feature-based與Cascade Classifier兩部份來說明。

Haar-like features

首先,所謂的Haar指的是哈爾特徵(Haar-like features),應用在機器學習領域的物件分類上是屬於監督學習的一種,它的中心思想是使用一個矩形window在待檢測的圖片來回的滑動,這個窗口每移動到一個位置就會計算出該區域的特徵值,然後用我們訓練好的級聯分類器(Cascade Classifier)對該特徵進行篩選,一旦該特徵通過了分類器的篩選,則判定該區域為人臉。

這些mask要目的就是為了把人臉特徵量化,以區分是人臉和不是人臉。計算方式是矩形中黑色區塊pixel值總和與白色區塊pixel值總和做相減,所獲取的值即為此分類器在該區域的特徵值。

每個窗口的特徵值 = 白色矩形的灰度值總和 – 黑色矩形的灰度值總和  「haar-like」的圖片搜尋結果

最早剛提出時,僅有下列五種形狀四種特徵,a, b屬於邊界特徵,c, d為細線特徵,e為對角線特徵。

後來經過數位大師的提出改進,哈爾特徵擴展成如下三大特徵:

「haar-like」的圖片搜尋結果

目前OpenCV支援下列十五種特徵:

Cascade Classifier

Cascade Classifier翻成中文是階層式分類器(亦有人翻為級聯分類器),它是由好幾個Classifier所組成以進行多層的分類。用在人臉偵測上的作法是一開始先將feature分成好幾個classifier,最先進行的classier辨識率最低,但是可以先篩選掉很大一部份不是人臉的圖片,接下來的Classier處理困難度較高的部份因此篩選掉的圖片會逐次減少,直到所有classier處理完為止,最後留下來的就會是我們想要的人臉的照片。

而對於上述的Haar來說,每一個基本的Haar-like特徵就是一個弱分類器(即識別率只比隨機識別好一點的演算法,可能是基於某些簡單規則的組合或少量樣本,強學習則是指一個演算法對其識別率很高),Kearns和Valiant兩位學者提出了弱學習和強學習等價的問題,證明了只要有足夠的dataset,弱學習算法就能通過集成(integration)的方式成為強學習,稱為Boosting演算法,後來再經過改良發展出權重概念的AdaBoost(自適應Boosting)演算法,此即為Cascade Classifier的基礎。

Cascade Classifier透過數個強分類器的組合(級聯),將每一張輸入的圖片依次通各個強分類器,前面的強分類器相對簡單,其包含的弱分類器也較少,後面的強分類器逐級複雜,只有通過前面的強分類檢測後的圖片才能進入後面的強分類器進行檢測,所以前面幾級的分類器已經過濾掉大部分不合格的圖片,只有通過了所有強分類器檢測的才是正確辨識出的圖片。

我們也可以使用openCV提供的指令來訓練自己的Haarcascades,此部份未來有機會再來實作,本文我們先使用opencv提供的正面人臉haarcascade_frontalface_alt.xml資料集,並搭配由兩個servo所組成的舵機雲台,作一個有趣的人臉追蹤器,

關於樹莓派的PWM

        樹莓派支援的硬體PWM腳位眾說紛紜有好幾種版本:

  1. 有的說PWM僅在第一代B版支援,而後所有的版本已取消均沒有PWM。
  2. 有的說樹莓派B僅有一支PWM腳位,而且與類比音效卡輸出共用,因此如果在板子上設定為Analog Audio out,那麼就不能用PWM了。
  3. 有的說樹莓派B有二支腳位支援PWM,分別是GPIO1和GPIO18,但GPIO1與音效卡的類比出共用,因此若使用Audio out時只能使用GPIO18的PWM。
  4. 還有的說樹莓派B有二支腳位支援PWM,分別是GPIO1和GPIO18,但這兩支分別與音效卡的立體聲類比輸出共用,因此使用Audio out時就無法使用。
  5. 另一種說法是支援PWM的腳位有七支,編號以GPIO_GEN開頭,如下圖GPIO表:

Pi3 pinout

        個人認為比較可信的為第D點,或許有空我們可來作個試驗,不過無論如何,在下方的實作中我們使用軟體PWM方式,透過GPIO.PWM來模擬PWM輸出,控制伺服馬達的運作。

動作流程

  我們的舵機雲台功能如下:

  1. 當PIR偵測到有人時會啟動舵機開始從上往下遞增30度、左右180度來回的轉動,搜尋是否有鏡頭內是否有臉孔出現,若有則鎖定持續追蹤,否則持續搜尋。
  2. 一個搜尋輪迴結束後,若PIR感測目前沒有人,則停止舵機的運作,並等待偵測到有人時再開始運作。

完成示範及程式碼

  相關程式已上載至Github:https://github.com/ch-tseng/PanTilt,您只要依照前方的作法,將舵機雲台的兩個servo分別接到pin 7與pin 11,PIR接到pin 36,LED接到pin 32,執行main.py即可運作。當然您也可以使用其它腳位,只要記得修改程式中相對應的參數值即可。

我也另外將舵機雲台寫成獨立的class,以方便未來應用在其它的專案上。您亦可以直接使用該pantilt.py函式庫在自己開發的專案中,使用方式很簡單:

一)匯入

from libCH.pantilt import PanTilt

二)建立物件,參數:PAN的pin腳12,TILT的pin腳11

motorPT = PanTilt(12,11)

三)啟動Pan/Tilt運作(開始傳入PWM,您會聽到servo轉動的聲音)

motorPT.start()

四)往右或左移動X距離(1相當於18度,例如要右移動90度,傳入參數X為5,往左移動90度則為-5)

motorPT.movePAN(X)

五)往上或下移動Y距離((1相當於18度,例如要上移動10度,傳入參數Y為-0.56,往下移動10度則為0.56)

motorPT.moveTILT(Y)

六)往右或往左移動到xDegree的位置(xDegree的範圍為2.5~12.5,對應於0~180度,因此若傳入xDegree=7.5,會轉到中間90度的位置)

motorPT.movePAN(xDegree)

七)往上或往下移動到yDegree的位置(yDegree的範圍為2.5~12.5,對應於0~180度,因此若傳入yDegree=7.5,會轉到中間90度的位置)

motorPT.moveTILT(yDegree)

八)停止Pan/Tilt運作(停止傳入PWM,servo會停止轉動)

motorPT.stop()

main.py(主程式)

請參考:https://github.com/ch-tseng/PanTilt/blob/master/main.py


libCH/pantilt.py (舵機雲台class)

請參考:https://github.com/ch-tseng/PanTilt/blob/master/libCH/pantilt.py

29 Comments

  1. 我的PIR不管怎麼放 都會偵測到東西
    我後來 改成 平常 上下左右都不要 旋動
    直到 影像 有辦識到人 才作追蹤 上下左右的tracking
    這樣可以增加零件的授命
    我覺得 用網路線傳輸 顯示 會快很多
    能夠完成作品 最後 感謝大大的指導

  2. 這段就是當PIR為1的時候才會開始tracking移動哦。程式中PIR 的Board Pin是32

    statusPIR = GPIO.input(pinPIR)

    if statusPIR == 1:
    if motorPT.inaction==0:
    #vs = VideoStream(usePiCamera=1).start()
    #time.sleep(2.0)
    motorPT.start()

  3. 我覺得我的PIR有問題
    我想 改成 平常 上下左右都不要 旋動
    直到 影像 有辦識到人 才作追蹤 上下左右的tracking
    我自己有改過 可是還是有問題?
    請問大大哥 往那幾行下手 可以達到目的?

  4. 謝謝大大回覆
    是調整這裡嗎?
    imgsize_w = int(640*0.4)
    imgsize_h = int(480*0.4)
    我是用我的人臉去辨識
    還是以上尺寸只識用於手機上的小圖片?
    請問大大用實際人臉,有建議的尺寸嗎?

  5. hi, 您看一下 checkFace() 這個function中的這段,if(facesNow>0):

    GPIO.output(pinLED, GPIO.HIGH)
    xFace = faces[0][0]
    yFace = faces[0][1]

    #print “x,y = " + str(xFace) + “," + str(yFace)
    diffX = (imgsize_w/2) – x
    diffY = (imgsize_h/2) – y
    print “diffX, diffY = " + str(diffX) + “," + str(diffY)
    movePANTILT(diffX, diffY)

    else:
    GPIO.output(pinLED, GPIO.LOW)
    facesNow = 0

    如果有抓到face就會movePANTILT()移動雲台, 您可以調整一下diffX, diffY的值看看。

    PIR是避免舵機雲台一直動很耗電,因此當有偵測到人時才開始左右移動,你可以把PIR放在想要偵測人的地方。

  6. 有比較好一點了
    可以左右上下旋動
    但是 偵測到人後 不會一直追蹤下去
    還是週期性的去找 左右上下 移動
    請問大大該如何作?

  7. 你的影片比我順超過10倍以上
    我執行後 伺服機 會很針雜的移動
    請問PIR正確位置要放到那裡?
    請問程式 大大 很來還有修改嗎?

  8. 所有功能,硬體,網路,顯示,都正常,有偵測到人臉也會亮燈
    我執行main.py,請問大大 如何才可以跟影片一樣 動作順暢?

  9. 1.putty我有打開X11 forwarding,請問putty要如何設定display?
    2.請問LCD如何接在樹莓派上在console上,LCD不是DSUB的頭嗎?

  10. 請謝大大哥回覆

    pi@raspberrypi:~/PanTilt $ sudo python main.py
    main.py:19:
    RuntimeWarning: This channel is already in use, continuing anyway.
    Use GPIO.setwarnings(False) to disable warnings.
    GPIO.setup(pinLED ,GPIO.OUT)
    /home/pi/PanTilt/libCH/pantilt.py:56: RuntimeWarning:
    This channel is already in use, continuing anyway.
    Use GPIO.setwarnings(False) to disable warnings.
    GPIO.setup(pinPAN, GPIO.OUT)
    /home/pi/PanTilt/libCH/pantilt.py:60: RuntimeWarning:
    This channel is already in use, continuing anyway.
    Use GPIO.setwarnings(False) to disable warnings.
    GPIO.setup(pinTILT, GPIO.OUT)
    PuTTY X11 proxy: Unsupported authorisation protocol
    (Frame:1079): Gtk-WARNING **: cannot open display: localhost:10.0

    main1.py 如以上所視 有問題?
    main2.py 可以執行.請問如何顯示 “人臉被偵測的執行畫面"

  11. 請問執行方式是這樣嗎?
    sudo python main.py
    出現錯誤
    Traceback (most recent call last):
    File “main.py", line 2, in
    from imutils.video import VideoStream
    ImportError: No module named imutils.video

  12. 請問Wu先生
    把git專案載入到pi後 然後要如何執行?(sudo python main.py <-不能動)
    opencv與硬體 我都有裝好
    PIR偵測 <- 請問這是什麼零件?
    麻煩Wu有空在回覆 謝謝

  13. sudo python main.py <-不能動
    請問把git專案載入到pi後 然後要如何執行?
    opencv與硬體 我都有裝好
    PIR偵測 <- 請問這是什麼零件?請問要去那裡買?
    麻煩版主大大有空在回覆 謝謝

迴響已關閉。