OpenCV入门初探---拿走就能用的 人脸检测小项目 源码分析

0x00思路概览

OpenCV入门初探---拿走就能用的 人脸检测小项目 源码分析

该程序整体逻辑是,识别你的脸并保存count(计数器)张你的脸的图片,然后退出,或者在运行中按q。

其中有两层重要的循环

1.持续调用摄像头循环-----while true

2.处理识别函数识别出的每张脸的函数-----for xywh in face

0x01代码概览

OpenCV入门初探---拿走就能用的 人脸检测小项目 源码分析

(分类器是啥?)-------F&A --2

0x02.相机逻辑分析

启动调用

camera = cv2.VideoCapture(0)#表示打开笔记本的内置摄像头

获取单个帧

光启动没用,需要捕获每一帧图片,编程而言,能细化的东西一定会尽量细化,想事情往往不能想的太过简单

ret, frame = camera.read()

这个ret用来反馈异常,如果截取不到帧则退出

释放

camera.release()

0x03.识别逻辑分析

转换

获取单个帧后,opencv读取图片的颜色通道排列时BGR,因此需要转换。

(深度学习中为什么普遍使用BGR而不用RGB?)----F&A 1

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)#将BGR格式转换成灰度图片

frame是上文每一帧图片的载体

第二个参数是图片格式,更多参数如下

识别函数

这里我们之前用gray接受了BGR格式的当前帧

faces = face_cascade.detectMultiScale(gray, 1.4, 5)

参数1:image--待检测图片,一般为灰度图像加快检测速度;

参数2:objects--被检测物体的矩形框向量组;

参数3:scaleFactor--表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%;

参数4:minNeighbors--表示构成检测目标的相邻矩形的最小个数(默认为3个)。

如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。

如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框,

这种设定值一般用在用户自定义对检测结果的组合程序上;

参数5:flags--要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果设置为 CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,因此这些区域通常不会是人脸所在区域;

参数6、7:minSize和maxSize用来限制得到的目标区域的范围。

返回值

具体函数细节暂时没看到,但根据下面的代码可以分析来,会返回每一张脸的矩形识别角坐标x,y(左下角)w,h即宽高,加上对应x,y就是右上角

框图反馈

 img = cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)

rectangle用来绘制矩形框 通常用在图片的标记上 参数:1.被处理图片 2.3矩形左上右下角坐标 4.颜色 5.线型

此时,你可以在电脑屏幕面前获得实时反馈。

frame是当前帧

0x04.存储逻辑

在整个程序开始前,我们需要给定一个路径作为参数,如果这个路径不是目录,我们就根据这个路径生成一个目录

给定参数是否为目录

    if (not os.path.isdir(dirname)):#判断是否为目录
        os.makedirs(dirname)#如果不是目录则创建目录

图片“格式化”

我们希望存储的照片格式一致

然后我们在这里要截取指定位置并缩放

文接3-识别函数,我们用gray存储了灰度图

f = cv2.resize(gray[y:y + h, x:x + w], (200, 200))

参数1:图片[位置],参数2:缩放为多大

写入

cv2.imwrite(dirname + '/%s.pgm' % str(count), f)#写入文件zhen

根据迭代器count命名

存照片

代码

import camera as camera
import cv2
import os


def generate(dirname):
    #1.加载人脸分类器
    face_cascade = cv2.CascadeClassifier('C:/Users/13956/Desktop/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')
    eye_cascade = cv2.CascadeClassifier('C:/Users/13956/Desktop/opencv/sources/data/haarcascades/haarcascade_eye.xml')
    # 带眼镜的时候可以用下面这个
    # eye_cascade = cv2.CascadeClassifier('C:/Users/13956/Desktop/opencv/sources/data/haarcascades/haarcascade_eye_tree_eyeglasses.xml')

    # 创建目录
    if (not os.path.isdir(dirname)):#判断是否为目录
        os.makedirs(dirname)#如果不是目录则创建目录

    # 打开摄像头进行人脸图像采集
    camera = cv2.VideoCapture(0)#表示打开笔记本的内置摄像头
    count = 0
    while (True):
        ret, frame = camera.read()#读取一帧的图片,ret获取返回值,frame是图片
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)#将BGR格式转换成灰度图片
        faces = face_cascade.detectMultiScale(gray, 1.4, 5)
        #利用训练好的数据识别,参数:输入图像  人脸目标序列  每次图像减小的比例  存储最小真识别认可   最小尺寸  最大尺寸
        #最后三个参数都可以降低误差
        for (x, y, w, h) in faces:#x,y是识别到的坐标,w,h是识别到的范围宽度,高度
            img = cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
            #rectang用来绘制矩形框 通常用在图片的标记上 参数:1.被处理图片 2.3矩形左上右下角坐标  4.颜色   5.线型
            # 重设置图像尺寸
            #200 * 200
            f = cv2.resize(gray[y:y + h, x:x + w], (200, 200))
            cv2.imwrite(dirname + '/%s.pgm' % str(count), f)#写入文件zhen
            print(count)
            count += 1#迭代器++

        cv2.imshow("camera", frame)
        if cv2.waitKey(100) & 0xff == ord("q"):
        #为何做掩码运算是因为已经发现在Linux中的某些情况下(when OpenCV uses GTK as its backend GUI),waitKey()可能返回超过ASCII的keycode,所以这是为了防止在某些情况下产生bug。
            break
    # 下面是你想要多少张图片就停止
        elif count > 20:
            break


    camera.release()#释放相机
    cv2.destroyAllWindows()#释放窗口

if __name__ == "__main__":
    #__name__是python的一个内置类属性,是标识模块的名字的一个系统变量。
    #如果当前模块被直接执行(主模块),__name__存储的是__main__

    #如果当前模块是被调用的模块(被导入),则__name__存储的是py文件名(模块名称)
    #在所有代码执行之前,__name__ 变量值被设置为 '__main__'
    generate("C:/Users/13956/Desktop/666") # 你生成的图片放在的电脑中的地方,调用函数

F&A

1.深度学习中为什么普遍使用BGR而不用RGB?

“因为caffe,作为最早最流行的一批库的代表,用了opencv,而opencv默认通道是bgr的。这是opencv的入门大坑之一,bgr是个历史遗留问题,为了兼容早年的某些硬件。

其实你自己训练完全可以用rgb,新库也基本没了bgr还是rgb这个问题,就是切换下顺序。但如果你要用一些老的训练好的模型,就得兼容老模型的bgr。
作者:HexUp
链接:https://www.zhihu.com/question/264044792/answer/277369496

2.分类器

Haar特征分类器就是一个XML文件,该文件中会描述人体各个部位的Haar特征值。包括人脸、眼睛、嘴唇等等。
Haar特征分类器存放目录:OpenCV安装目录中的\data\ haarcascades目录下,opencv2.4.9版本下的Haar特征分类器如下:

haarcascade_eye.xml
haarcascade_eye_tree_eyeglasses.xml
haarcascade_frontalface_alt.xml
haarcascade_frontalface_alt_tree.xml
haarcascade_frontalface_alt2.xml
haarcascade_frontalface_default.xml
haarcascade_fullbody.xml
haarcascade_lefteye_2splits.xml
haarcascade_lowerbody.xml
haarcascade_mcs_eyepair_big.xml
haarcascade_mcs_eyepair_small.xml
haarcascade_mcs_leftear.xml
haarcascade_mcs_lefteye.xml
haarcascade_mcs_mouth.xml
haarcascade_mcs_nose.xml
haarcascade_mcs_rightear.xml
haarcascade_mcs_righteye.xml
haarcascade_mcs_upperbody.xml
haarcascade_profileface.xml
haarcascade_righteye_2splits.xml
haarcascade_smile.xml
haarcascade_upperbody.xml

这里我们用的是

haarcascade_frontalface_default.xml特征值文件

xml里面的数据都是深度学习训练好的数据,具体需要去看深度学习相关的内容

上一篇:python tkinter知识点使用记录


下一篇:ffplay源码分析4-音视频同步