您的位置:首页 > 编程语言 > C语言/C++

基于OpenCV的人脸检测——C++和Python实现

2017-01-21 20:41 1156 查看
弄了一天终于实现了简单的人脸识别,参考学习的书籍《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语言实现》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: