0x00思路概览
该程序整体逻辑是,识别你的脸并保存count(计数器)张你的脸的图片,然后退出,或者在运行中按q。
其中有两层重要的循环
1.持续调用摄像头循环-----while true
2.处理识别函数识别出的每张脸的函数-----for xywh in face
0x01代码概览
(分类器是啥?)-------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里面的数据都是深度学习训练好的数据,具体需要去看深度学习相关的内容