更多课程 选择中心

Python培训
美国上市教育机构

400-111-8989

Python培训

一篇文教你学会用Python实现Opencv人脸识别

  • 发布:创客大爆炸
  • 来源:创客大爆炸
  • 时间:2018-03-05 11:55

基础配置

系统:Ubuntu 16.04 LTS

opencv : opencv3.2.0 + opencv-contrib

python : python2.7

由于版权问题,opencv的人脸识别方法模块移植到了opencv-contrib中,所以要用opencv实现人脸识别,对opencv的版本有两种选择:

(1) opencv3.2.0+opencv-contrib  

(2) opencv2/opencv3.1.0

参考链接:手动编译opencv3.2.0 + opencv-contrib

参考链接:为指定conda环境编译安装opencv

打开摄像头

#!/usr/bin/env python3# -*- coding: utf-8 -*-import cv2
cap = cv2.VideoCapture(0)while(True):
    ret, frame = cap.read()
    result = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    cv2.imshow("camera",result)
    if cv2.waitKey(40) & 0xFF == ord("q"):
        breakcap.release()
cv2.destroyAllWindows

知识点:

  1. 引用模块

import cv2
  1. 捕获摄像头

# 参数0表示本机摄像头# 参数1表示外接摄像头cap = cv2.VideoCapture(0)
  1. 获取每一帧的画面

# ret 为标志位,true表示成功捕获,false表示失败# frame 为获取的每一帧图片ret, frame = cap.read()
  1. 转换图片的色彩空间

# 参数1 图片对象# 参数2 转换参数# 这里把图片转为灰度图result = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
  1. 显示图片

# 参数1 显示图片窗口的名字# 参数2 图片对象cv2.imshow("camera",result)
  1. 执行等待

/*参数为一个毫秒数#(1)在这个时间内,按下按键,返回键位的ASCII码,程序继续执行#(2)在这个时间内,没有按下按键,返回255,程序继续执行#(3)参数<=0,一直等待,直到按下按键,然后程序继续执行 # cv2.imshow()后面必须带cv2.waitKey(),否则图片不会显示*/cv2.waitKey(40)
  1. 释放摄像头

cap.release()
  1. 销毁所有窗口

cv2.destroyAllWindows

图片进行人脸检测

haarcascade_frontalface_default.xml  

存放在opencv>data>haarcascades 下

用于人脸检测

#!/usr/bin/env python3# -*- coding: utf-8 -*-import cv2filename = "./image1.jpg"def detect(filename):
    cascade_face = cv2.CascadeClassifier("./haarcascade_frontalface_default.xml")
    img = cv2.imread(filename)
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    face = cascade_face.detectMultiScale(gray,1.3,5)
    print face
    for (x,y,w,h) in face:
        img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
    
    cv2.namedWindow("detect_face")
    cv2.imshow("detect_face",img)
    cv2.imwrite("detected_face.jpg",img)
    if cv2.waitKey(0) & 0xFF == ord("q"):
        return
detect(filename)

知识点:

  1. 创建级联分类器

# 参数为训练完毕的xml模型文件路径cv2.CascadeClassifier("xml_path")
  1. 人脸检测函数

# 获取人脸的检测结果# face 为(x,y,w,h)元祖构成的列表# 参数1 灰度图对象# 参数2 scaleFactor 人脸检测过程中每次迭代时图像的压缩率# 参数3 minNeighbors 每个人脸矩形保留近邻数目的最小值face = cascade_face.detectMultiScale(gray,1.3,5)
  1. 画框

# 参数1 图片对象# 参数2 矩形框的左上角坐标# 参数3 矩形框的宽和高# 参数4 矩形框的颜色// 参数5 矩形框的线宽cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
  1. 保存图片

# 参数1 保存地址# 参数2 图片对象cv2.imwrite("detected_face.jpg",img)

效果:

摄像头进行人脸检测

#!/usr/bin/env python3# -*- coding: utf-8 -*-import cv2
def detect():
    cascade_face = cv2.CascadeClassifier("./haarcascade_frontalface_default.xml")
    cap = cv2.VideoCapture(0)
    cv2.namedWindow("camera")
    while(True):
        ret, frame = cap.read()
        gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        face = cascade_face.detectMultiScale(gray,1.3,5)
        for (x,y,w,h) in face:
            cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
        cv2.imshow("camera",frame)
        if cv2.waitKey(40) & 0xFF == ord("q"):
            break    cap.release()
    cv2.destroyAllWindows()

detect()

效果:

摄像头进行人脸识别

人脸识别分4个步骤:

(1) 采集人脸样本

(2) 生成label.text

(3) 训练自己的数据模型

(4) 人脸识别

项目根目录为:/home/gjl/workSpace/predict_face

完整的目录结构:

最终效果:

(1) 采集人脸样本

运行 user:***$ python2  get_samples+sample_name.py  sample_name

运行时输入样本名称,作为采集的保存路径

× 点击“w”,确认采集脸部样本

× 点击“q”,退出

import cv2
import sys
import oscount = 0def get_samples():
    cascade_face = cv2.CascadeClassifier("./haarcascade_frontalface_default.xml")
    cap = cv2.VideoCapture(0)
    cv2.namedWindow("get_samples")

    if(len(sys.argv)) < 2:
        print "error: >>> get_samples.py <sample_name>"        sys.exit()
    sampleName = sys.argv[1]
    new_path = os.getcwd()+'/'+ sampleName
    print new_path
    flag = os.path.exists(new_path)
    print flag
    if(flag):
        print "+++++++++++++"    else:
        os.mkdir(sampleName)

    def get_sample(sampleName,gray,x,y,w,h):
        global count        print sampleName
        sample_face = cv2.resize(gray[y:y+h,x:x+w],(200,200))
        cv2.imwrite('./%s/%s.pgm' % (sampleName,str(count)),sample_face)
        count += 1    
    while(True):
        ret, frame = cap.read()
        gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        face = cascade_face.detectMultiScale(gray,1.3,5)
        for (x,y,w,h) in face:
            cv2.rectangle(gray,(x,y),(x+w,y+h),(0,255,0),2)     
        cv2.imshow("get_samples",gray)
        key = cv2.waitKey(40)
        if key==ord("q"):
            break        elif key == ord("w"):
            print "---------------------"            get_sample(sampleName,gray,x,y,w,h)
            
    cap.release()
    cv2.destroyAllWindows()
    
get_samples()

知识点:

  1. 获取python外部的命令参数

# sys.srgv[0]  运行文件本身# sys.srgv[1]  运行文件后面带的参数# 下面截图中 通过sys.argv[1] 获取到的就是 ALisys.argv

  1. 获取当前运行文件的绝对路径

os.getcwd()
  1. 判断文件夹/文件是否存在

# 存在 返回True# 不存在 返回Falseos.path.exists(new_path)
  1. 创建文件夹

os.mkdir(dir_name)
  1. 压缩图片

// 参数1 图片对象// 参数2 (width,height)cv2.resize(gray[y:y+h,x:x+w],(200,200))

采集完以后的效果:

(2) 生成label.text

运行 user:***$ python2  get_samples+sample_name.py  sample_path

运行时输入根目录

import cv2import osimport numpy as npimport sysc = 0def get_label(path):
    global c    fh = open("./label.text",'w')
    for dirname,dirnames,filename in os.walk(path):
        for subdirname in dirnames:
            subject_path = os.path.join(dirname,subdirname)
            for filename in os.listdir(subject_path):
                if(filename == '.directory'):
                    contine
                filepath = os.path.join(subject_path,filename)
                fh.write(filepath);
                fh.write(";")
                fh.write(str(c))
                fh.write("\n")
            c = c+1            
    fh.close()
    print "label.text saved ok"if len(sys.argv) < 2:
    print ">>> python2 predict_face.py <your_samples_path>"    sys.exit()
get_label(sys.argv[1])

效果:

根目录下生成label.text


(3) 训练自己的数据模型

import cv2import osimport numpy as np

images = []
labels = []
fh = open("./label.text")
cv2.namedWindow("show_img")for line in fh:
    #print line,
    arr = line.split(";")
    img = cv2.imread(arr[0],0)
    images.append(img)
    labels.append(int(arr[1][:-1]))
    #print arr[0],arr[1]
    cv2.imshow("show_img",img)
    cv2.waitKey(20)
    
model = cv2.face.createEigenFaceRecognizer()
#labels = np.asarray(labels,dtype=np.int32)
model.train(np.asarray(images),np.asarray(labels))
model.save("./predict_face_ALi_HaiPeng_XiaoBo.xml")print "trained"

知识点:

  1. 创建人脸检测模型

model = cv2.face.createEigenFaceRecognizer()
  1. 训练数据

// 参数1 图像数组// 参数2 标签数组model.train(np.asarray(images),np.asarray(labels))
  1. 保存模型

# 参数 生成xml的路径model.save("./predict_face_ALi_HaiPeng_XiaoBo.xml")

注意:

  1. 在labels.append()时,要把ID通过int()转化为整形

  1. 在python中 [ ] 表示列表,而不是数组

  1. model.train( ),传入的必须是数组,所以需要通过np.asarray() 把列表转为数组

效果:

在根目录下生成我们需要的xml文件

(4) 人脸识别

运行 user:***$ python2  recognize+model_name.py  model_name

运行时输入模型名称

import cv2
import os
import sys

path = "/home/gjl/workSpace/predict_face"name = []

face_cascade = cv2.CascadeClassifier("./haarcascade_frontalface_default.xml")
model = cv2.face.createEigenFaceRecognizer()if(len(sys.argv)) < 2:
    print "error: >>> get_samples.py <your_model_name>"    sys.exit()
model.load("./"+sys.argv[1])for dirname,dirnames,filename in os.walk(path):
    for subdir in dirnames:
        name.append(subdir)print namecap = cv2.VideoCapture(0)
cv2.namedWindow("recognize")while(True):
    ret, frame = cap.read()
    print ret    gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.3, 5)
    for (x,y,w,h) in faces:
        cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
        face = cv2.resize(gray[y:y+h,x:x+w],(200,200))
        params = model.predict(face)
        print "Label: %s ,Confidence: %.2f" % (params[0],params[1])
        cv2.putText(frame,name[params[0]],(x,y-20),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),2)
        cv2.putText(frame,str(params[0]),(x,y+h+25),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),2)
        cv2.putText(frame,str(params[1]),(x+50,y+h+25),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),2)
    cv2.imshow("recognize",frame)
    if cv2.waitKey(40) & 0xFF==ord("q"):
        break    cap.release()
cv2.destroyAllWindows()

知识点:

  1. 加载xml模型

# 参数 xml路径model.load("./"+sys.argv[1])
  1. 识别

# 参数 待识别的图片对象# 返回params 即含有两个参数的数组# 返回的第一个参数 识别个体的标签# 返回的第二个参数 置信度评分 0表示完全匹配params = model.predict(face)

最终效果:

先前已给出


预约申请免费试听课

填写下面表单即可预约申请免费试听!怕钱不够?可就业挣钱后再付学费! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

上一篇:Python实现工厂模式的两个例子
下一篇:达内Python培训学员都在做什么?能拿多少工资?

Python编程练习三

Python正则表达式练习

Python 2的结束意味着什么

用python做一个划词翻译软件

选择城市和中心
黑龙江省

吉林省

河北省

湖南省

贵州省

云南省

广西省

海南省