面部检测

 

一次人脸识别的摸鱼认真学习经历

这几天看见一个SIRB实验室好像有点意思,遂去参加招新,里面选了个人脸识别方向玩玩。这几天就在做这个东西。

其中人脸检测部分已经做的差不多了,就想着先写个博客,总结一下。

人脸检测我找到两个轮子,一个是python-opencv里的自带的轮子,采用的是haar算法,另一个是python有人已经做好封装的face_recognition库,装起来也挺容易的。本来看见一个cnn深度学习的算法api,本来想也弄起来玩,无奈CUDA并不支持我的显卡,只好作罢。

招新题目里推荐的是使用opencv实现人脸检测,附加是人脸识别名字。先做出人脸检测部分,话不多说上源码:

import numpy as np 
import cv2 

FaceCascade = cv2.CascadeClassifier(r'./haarcascade_frontalface_default.xml') 

EyeCascade = cv2.CascadeClassifier(r'./haarcascade_eye.xml')

GrassesEyeCascade = cv2.CascadeClassifier(r'./haarcascade_eye_tree_eyeglasses.xml')

#上面这三个分别是调用xml里的识别文件对面部、眼镜、有眼镜的眼镜进行检测,建议使用绝对路径
#这些文件一般都在opencv/build/etc/haarcascades目录下。
img = cv2.imread(r'./me.jpg')
#获取图片
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# cv2.imshow('233',gray)
#转成灰度图
Faces = FaceCascade.detectMultiScale(
	gray,
	scaleFactor=1.2,
	minNeighbors=5,
	minSize=(32,32)
)
#这里是识别,里面有一些乱七八糟的参数
'''
参数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用来限制得到的目标区域的范围。
  从CSDN摘录
'''
for (x, y, w, h) in Faces:
	fac_gray = gray[y:(y+h),x:(x+w)]
	# cv2.imshow('233',fac_gray)
    # 剪下脸部区域,继续识别眼睛
	result = []
	eyes = EyeCascade.detectMultiScale(fac_gray,1.3,2)
	glasses = GrassesEyeCascade.detectMultiScale(fac_gray,1.3,2)
	for (ex, ey, ew, eh) in eyes:
		result.append((x+ex, y+ey, ew, eh))
	for (gx,gy,gw,gh) in glasses:
		result.append((x+gx, y+gy, gw, gh))

for (x,y,w,h) in Faces:
	cv2.rectangle(img, (x, y), (x+w, y+h), (255,0,0), 2)
#在脸部画出长方形
for (ex, ey, ew, eh) in result:
	cv2.rectangle(img, (ex,ey), (ex+ew, ey+eh), (0,255,0) ,10)
#在眼部画出长方形
for (gx,gy,gw,gh) in result:
	cv2.rectangle(img, (gx,gy), (gx+gw,gy+gh), (0,0,255),10)

img1 = cv2.resize(img,(0,0),fx=0.1,fy=0.1,interpolation=cv2.INTER_NEAREST)
#缩放图片
cv2.imshow('stange image add!', img1)
# 显示图片
cv2.waitKey(0)
cv2.destroyAllWindows()

为了玩耍的更加愉快,自然是要使用摄像头进行实时的人脸识别好玩啊。所以说第二个源码我加入了摄像头来玩。不过在做这个事情的时候我发现不管怎么搞,配环境,加入库和插件,排错,摄像头都是显示黑色,这让我百思不得其解。直到我发现我的笔记本摄像头被我挡住了,根本没有拉出来为止。(玩硬件要先检查下硬件状况,学到了

这里代码采用了face_recognition来进行识别,只做到识别面部。

import face_recognition
import cv2


cap = cv2.VideoCapture(0)
flag = True
#摄像头打开
while flag:
	flag, img = cap.read()
#读取
	gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#灰化
	Faces = face_recognition.face_locations(img)
#识别
	for(x,y,w,h) in Faces:
		cv2.rectangle(img, (y,x), (h,w),(255,0,0),2)
#画图	
	cv2.imshow('233',img)
	k = cv2.waitKey(1)
	if k==27:
        #按下ESC退出
		break

cap.release()
cv2.destroyAllWindows()
#释放 关闭摄像头 以及所有窗口

除了面部检测,面部识别的haar写法也已经写好了,8过下个文章发吼了。

搞了这个以后想试试验证码的噪点清除什么的,一点点简单的开始慢慢搞起。

参考文章:https://www.cnblogs.com/xp12345/p/9818435.html

https://github.com/ageitgey/face_recognition/issues/175#issue-257710508

https://blog.csdn.net/Marksinoberg/article/details/52443214