人臉追蹤的第一步,當然是要讓 Raspberry Pi 先認識人臉囉... 這裡使用的是 AI 影像辨識非常成熟的 OpenCV... 因為我跟 C 非常不熟,所以使用 Python 來調用 OpenCV...

OpenCV 是甚麼?去Google一下,會看到很多文章,我沒有比這些大神懂更多,就不多說了... 有興趣可以去 WiKi 稍微了解一下... 

Python + OpenCV 在 Windows 很多人玩,安裝也相對簡單,因為已經有大神幫忙做好自動安裝檔了。 不幸的是,我要用 Raspberry Pi,他是 Linux + ARM,有大神做好了 OpenCV for C 的安裝檔,但是沒有 OpenCV for Python 的安裝檔,所以得要跟著前輩的指示,一步一步的自己 Compile... 還好前輩的指引還算清楚,只是要花時間,就順便練習一下,如何在 Raspberry Pi 上 Compile Source Code 囉...

安裝 OpenCV 的步驟,基本上請按照 http://atceiling.blogspot.tw/2017/02/raspberry-pi-opencv.html 的指示... 有一個重點要注意... 請使用 16GB 以上的 microSD 來玩 OpenCV !! 因為 OpenCV 真的很熱門,很多大神提供了非常完善的資料庫,只用 8GB 的記憶卡是裝它不下的...

稍為順一下...

Step 1 : 安裝套件

## 系統升級

    pi@rpi:~ $ sudo rpi-update ; sudo apt-get update ; sudo apt-get upgrade    

## 安裝編譯工具

    pi@rpi:~ $ sudo apt-get install -y build-essential git cmake pkg-config    

## 安裝影像 IO 套件

    pi@rpi:~ $ sudo apt-get install -y libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev    ## libjpeg8-dev cannot install     

    pi@rpi:~ $ sudo apt-get install -y libavcodec-dev libavformat-dev libswscale-dev libv4l-dev 

    pi@rpi:~ $ sudo apt-get install -y libxvidcore-dev libx264-dev    

    pi@rpi:~ $ sudo apt-get install -y libgtk2.0-dev python2.7-dev    

    pi@rpi:~ $ sudo apt-get install -y libatlas-base-dev gfortran

Step 2 : 下載 OpenCV

    pi@rpi:~ $ wget -O opencv_3.2.0.zip https://github.com/opencv/opencv/archive/3.2.0.zip

    pi@rpi:~ $ unzip opencv-3.2.0.zip

    pi@rpi:~ $ cd opencv-3.2.0

Step 3 : 安裝設定 Python 虛擬環境 (VirtualEnv)

    pi@rpi:~ $ sudo pip install virtualenv ; sudo pip install virtualenvwrapper    

    pi@rpi:~ $ nano ~/.profile    ## Modify Setting for VirtualEnv, add below parameter    

# virtualenv and virtualenvwrapper 
export WORKON_HOME=$HOME/.virtualenvs 
source /usr/local/bin/virtualenvwrapper.sh

    pi@rpi:~ $ source ~/.profile ; mkvirtualenv cv ; workon cv   

Step 4 : 編譯與安裝 OpenCV

    pi@rpi:~ $ workon cv ; cd ~/opencv-3.2.0/ ; mkdir build ; cd build    

(cv) pi@rpi:~/opencv-3.2.0/build $ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_NEW_PYTHON_SUPPORT=ON -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=ON ..  

(cv) pi@rpi:~/opencv-3.2.0/build $ make -j4    ## Need 30-60min to build

(cv) pi@rpi:~/opencv-3.2.0/build $ cd ~/.virtualenvs/cv/lib/python2.7/site-packages/ ; ln -s /usr/local/lib/python2.7/site-packages/cv2.so  cv2.so  

Step 5 : 確認是否安裝成功?整個安裝過程大概半天...

    pi@rpi:~ $ workon cv 
(cv) pi@rpi:~ $ python 
>>> import cv2 
>>> cv2.__version__ 
'3.2.0'

 


接著才是重點,寫一個人臉辨識程式來玩玩...

基本上參考 https://realpython.com/blog/python/face-recognition-with-python/ 這篇文章... 怕英文看不清楚,順便看一下 這一篇 ...

    pi@rpi:~ $ nano test_cv.py

#!/usr/bin/env python
# import the necessary packages
import time
import cv2
import sys

GRAY_MODE = False
 
faceXML = "haarcascade_frontalface_alt.xml"
faceCascade = cv2.CascadeClassifier(faceXML)
eyeXML = "haarcascade_eye_tree_eyeglasses.xml"
eyeCascade = cv2.CascadeClassifier(eyeXML)
 

def detectFace(gray):
    # Define Face Detect Scale
    faces = faceCascade.detectMultiScale(
        gray,
        scaleFactor=1.1,
        minNeighbors=5,
        minSize=(30, 30),
        flags=cv2.CASCADE_SCALE_IMAGE
    )
    return(faces)
    
def detectEye(gray):
    eyes = eyeCascade.detectMultiScale(
        gray,
        scaleFactor=1.1,
        minNeighbors=5,
        minSize=(30, 30),
        flags=cv2.CASCADE_SCALE_IMAGE
    )
    return(eyes)
    
def drawCross(img, x, y):
    cv2.circle(img, (x, y), 10, (0, 255, 0), 1)
    cv2.line(img, (x-20, y), (x+20, y), (0, 255, 0), 1)
    cv2.line(img, (x, y-20), (x, y+20), (0, 255, 0), 1)
    

def main():
    if len(sys.argv) <2:
        print("\n\n --- User no Input ---")
    
    else:
        print("\n\n --- User Input : %s "%sys.argv[1])
        if sys.argv[1].split('.')[-1].lower() in 'jpg, png':
            print("    --> Image File")
            t0 = time.time()
            image = cv2.imread(sys.argv[1])
            gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
            faces = detectFace(gray)
            eyes  = detectEye(gray)
            area, pos_x, pos_y = 0, 0, 0
            for (x, y, w, h) in faces:
                cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
                area_tmp = w*h
                if area_tmp > area:
                    area = area_tmp
                    pos_x = x + w/2
                    pos_y = y + h/2
            for (x, y, w, h) in eyes:
                cv2.rectangle(image, (x, y), (x+w, y+h), (255, 0, 0), 2)
            cv2.putText(image, "Face Pos : (%d, %d)"%(pos_x, pos_y), (10,50), cv2.FONT_HERSHEY_TRIPLEX, 1, (255,0,255), 1)
            
            # show the frame
            drawCross(image, pos_x, pos_y)
            cv2.imshow("Detect Face - Done", image)
            t0p = time.time() - t0
            print("\n\n --- Detect %d Faces in %s --- Use %.1f sec"%(len(faces), sys.argv[1], t0p ))
            cv2.waitKey(0)
        elif sys.argv[1].split('.')[-1].lower() in 'avi, mp4':
            video_capture = cv2.VideoCapture( sys.argv[1] )
            #video_capture = cv2.VideoCapture(0)

            while True:
                ret, frame = video_capture.read()
                gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
                faces = detectFace(gray)
                for (x, y, w, h) in faces:
                    cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
                # Display the resulting frame
                cv2.imshow("Video - Press 'q' to stop", frame)
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    video_capture.release()
                    cv2.destroyAllWindows()
                    break
        
            # When everything is done, release the capture
            cv2.imshow("Detect Face - Done", frame)
            cv2.waitKey(0)
            cv2.destroyAllWindows()
        

if __name__ == "__main__":
    main()
    sys.exit()

 

上面存成 .py 檔,再去網路抓一張有人臉的圖來測試...

    pi@rpi:~ $ workon cv 
(cv)    pi@rpi:~ $ python test_cv.py Girl_Generation.jpg

--- User Input : Girls_Generation.jpg 
    --> Image File


 --- Detect 5 Faces in Girls_Generation.jpg --- Use 4.1 sec

結果如下圖,辨識人臉用了 4.1 sec...

RPi_Face_Detect_Girl_Generation.jpg

人臉辨識率 5/8... 還不錯... 關鍵是 我使用的人臉特徵是 OpenCV 內附的,臉要才認的出來...

對了,特徵檔在 OpenCV 的資料夾底下,請先 copy 出來,跟 test_cv.py 放在同一個目錄下...

(cv)    pi@rpi:~ $ cp ~/opencv-3.2.0/data/haarcascades/haarcascade_frontalface_alt.xml ~/ ; cp ~/opencv-3.2.0/data/haarcascades/haarcascade_eye_tree_eyeglasses.xml ~/

下一篇:人臉追蹤相機-相機雲台

arrow
arrow
    文章標籤
    Raspberry Pi Python OpenCV
    全站熱搜
    創作者介紹
    創作者 Webb 的頭像
    Webb

    我的Maker之路

    Webb 發表在 痞客邦 留言(0) 人氣()