基于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 faces; //保存人脸位置
    std::vector 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 
#include 
#include 
#include 
#include 
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语言实现》

你可能感兴趣的:(Python,机器学习)