1. 程式人生 > >基於OpenCV的人臉檢測——C++和Python實現

基於OpenCV的人臉檢測——C++和Python實現

弄了一天終於實現了簡單的人臉識別,參考學習的書籍《OpenCV影象處理程式設計例項》裡的程式碼並不合適,可能是我並沒有完全照抄書上的程式的原因,但是《OpenCV3計算機視覺Python語言實現》一書中關於人眼檢測那部分程式碼也是不行的,最後經過自己的簡單修改才實現的最後效果。
本來之前用著VS2013 Pro(版本VC12)的,但是前幾天電腦中毒了系統環境變數PATH全沒了,VS2013也打不開,重新設定之後還是有問題,昨天又花了一晚的時間將OpenCV3.1用TDM-GCC編譯出來,在codeblocks16.04上編寫工程,之前對codeblocks瞭解不多,這幾天也正好學習了。下面記錄一下今天的結果(主要是貼程式碼了~~),以備日後自己參考和提供入門新手的一些借鑑。

系統環境:win10 64bit

C++實現:

編譯器Compiler: TDM-GCC64(基於GCC5.1.0)
整合開發環境IDE:Codeblocks16.01 ,我之前的一篇文章說codeblocks下載自帶mingw編譯器的,但是從官網的說明來看mingw是32位版本的,也是基於TDM-GCC的,如果需要64位的就要另外安裝TDM-GCC64。另外可以提一下mingw(mingw32),mingw64和TDM-GCC是不同的,具體可以自行搜尋,總的來說TDM-GCC效能最穩定。

下面是檢測的子函式,大部分都有註釋了:

int detectfaces(Mat frame)
{
    cv::CascadeClassifier face_cascade,eyes_cascade;
    cv::String window_name = "Face detect"
; /*!//載入Haar級聯檔案,由此執行人臉檢側和人眼檢測!*/ face_cascade.load("haarcascade_frontalface_default.xml"); eyes_cascade.load("haarcascade_eye.xml"); std::vector<Rect> faces; //儲存人臉位置 std::vector<Rect> eyes; //儲存人眼位置 Mat grayImg ; cvtColor(frame, grayImg,COLOR_BGR2GRAY); //轉化為灰度圖
equalizeHist(grayImg,grayImg); //直方圖均衡 //多尺度人臉檢測 face_cascade.detectMultiScale(grayImg, faces, 1.1, 3, 0|CASCADE_SCALE_IMAGE, Size(30,30)); //人臉檢測結果判定 for(size_t i = 0;i < faces.size(); i++) { Point center(faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2); Point pt1(faces[i].x,faces[i].y); //矩形左上角座標 Point pt2(faces[i].x+faces[i].width, faces[i].y+faces[i].height); //矩形右下角座標 Mat face = grayImg(faces[i]); rectangle(frame,pt1,pt2,Scalar(255,0,0),4); //繪製矩形,藍色邊框(BGR格式),邊框大小為4 /*!書籍上第一個引數是face,即人臉區域,但是不行,最後換成轉換出來的灰度圖就可以了, 原因不明,還在繼續學習中!*/ eyes_cascade.detectMultiScale(grayImg, eyes, 1.33, 2, 0 | CASCADE_SCALE_IMAGE, Size(30,30)); }

主函式:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char *argv[])
{
    VideoCapture cap(0); //新建VideoCapture物件
    Mat frame;
    while(cap.read(frame)) //開啟攝像頭
    {
        detectfaces(frame);
        if(char(waitKey(1))=='Q') //如果按下‘Q'就退出
            break;
    }
    return 0;
}

Python實現:

IDE: 輕量級的IDE——Pyzo ,效能很穩定,可以方便切換python2和python3環境,支援tab自動補全程式碼,當然,不足之處就是介面主題單一無法修改等。順便提一下,我自己用的是IEP3.7 (IEP是Pyzo老版本,官網有說明),本來一開始也是安裝了最新版本的Pyzo4.3.1,但是安裝完之後執行mayavi的函式會報錯,提示說mayavi不支援Pyqt5,查看了一下Pyzo的安裝檔案都是PyQT5的,應該是這裡起衝突了,換回IEP3.7就沒問題了。

程式碼如下:

import cv2


##下面的haarcascade_frontalface_alt2.xml和cascades\\haarcascade_eye.xml在opencv3.1原始碼的$opencv_source_path$/data/haarcascades下面,本地沒有原始碼的話可以去github線上找

def detect():
    face_cascade = cv2.CascadeClassifier("D:\\Files\\python\\python2\\facialdetect\\cascades\\haarcascade_frontalface_alt2.xml") #載入級聯檔案

    eye_cascade = cv2.CascadeClassifier("D:\\Files\\python\\python2\\facialdetect\\cascades\\haarcascade_eye.xml")

    cap = cv2.VideoCapture(0) #開啟攝像頭

    while (cap.isOpened()):   #如果打開了攝像頭
        ret,frame = cap.read()  #獲取幀資料
        gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)    #轉化為灰度圖
        faces = face_cascade.detectMultiScale(gray,1.3,5) #人臉檢測

        for (x,y,w,h) in faces: 
            img = cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2) #繪製矩形
            #同樣,書籍的程式碼是給出 roi_gray 這個人臉區域來識別眼睛,但是不行,大家可以試試把下面引數 img 改回roi_gray
            #roi_gray = gray[y:y+h,x:x+w]
            eyes = eye_cascade.detectMultiScale(img,1.03,5,0,(30,30)) #人眼檢測

        for (ex,ey,ew,eh) in eyes:
            cv2.rectangle(frame, (ex,ey), (ex+ew,ey+eh),(0,255,0),2) #繪製矩形
            cv2.imshow('face',frame)

        if cv2.waitKey(1) & 0xff == ord("Q"):
            break

    cap.release()    
    cv2.destroyAllWindows()

detect()

最終截圖就不貼出來了,從結果可以發現用Python的效果比較好,自己也沒怎麼去調引數了,detectMultiScale函式的一些引數可以調整來改變效果的。暫時先記錄到這裡了!

參考資料:
《OpenCV影象處理程式設計例項》
《OpenCV3計算機視覺Python語言實現》