目录
(1)选题简介
- 新冠肺炎疫情蔓延,各地防控措施严格,众多应届毕业生无法返回学校,大学生生涯重要纪念——毕业照面临无法拍摄的窘境,由此许多高校毕业生自发用P图的方式,打造自己班级的毕业照。我们小组希望借助这次大作业的契机,结合树莓派和微服务打造一个简单实用的云毕业照。
(2)设计部署
设计
1.基于LBPH原理的人脸识别
- LBPH(Local Binary PatternsHistograms)局部二进制编码直方图,建立在LBPH基础之上的人脸识别法基本思想如下:首先以每个像素为中心,判断与周围像素灰度值大小关系,对其进行二进制编码,从而获得整幅图像的LBP编码图像;再将LBP图像分为个区域,获取每个区域的LBP编码直方图,继而得到整幅图像的LBP编码直方图,通过比较不同人脸图像LBP编码直方图达到人脸识别的目的,其优点是不会受到光照、缩放、旋转和平移的影响。
2.部分代码
人脸收集
def data_collection():
cap = cv2.VideoCapture(0)
# cv2.CAP_DSHOW是作为open调用的一部分传递标志,还有许多其它的参数,而这个CAP_DSHOW是微软特有的。
face_id = input('
请输入你的ID:')
print('
数据初始化中,请直视摄像机录入数据....')
count = 0
while True:
# 从摄像头读取图片
sucess, img = cap.read()
# 转为灰度图片
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 检测人脸
faces = face_detector.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x + w, y + w), (255, 0, 0))
count += 1
# 保存图像
cv2.imwrite("facedata/Member." + str(face_id) + '.' + str(count) + '.jpg', gray[y: y + h, x: x + w])
cv2.imshow('data collection', img)
# 保持画面的持续。
k = cv2.waitKey(1)
if k == 27: # 通过esc键退出摄像
break
elif count >= 200: # 得到n个样本后退出摄像
break
cap.release()
cv2.destroyAllWindows()
人脸训练
def face_training():
# 人脸数据路径
path = './facedata'
recognizer = cv2.face.LBPHFaceRecognizer_create()
def getImagesAndLabels(path):
imagePaths = [os.path.join(path, f) for f in os.listdir(path)] # join函数将多个路径组合后返回
faceSamples = []
ids = []
for imagePath in imagePaths:
PIL_img = Image.open(imagePath).convert('L') # convert it to grayscale
img_numpy = np.array(PIL_img, 'uint8')
id = int(os.path.split(imagePath)[-1].split(".")[1])
faces = face_detector.detectMultiScale(img_numpy)
for (x, y, w, h) in faces:
faceSamples.append(img_numpy[y:y + h, x: x + w])
ids.append(id)
return faceSamples, ids
print('数据训练中')
faces, ids = getImagesAndLabels(path)
recognizer.train(faces, np.array(ids))
recognizer.write(r'./trainer.yml')
人脸识别
def face_ientification(sourcePath, targetPath, suffix):
ImagePaths = getAllPath(sourcePath, suffix)
count = 1
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('./trainer.yml')
faceCascade = cv2.CascadeClassifier(Path)
global namess
for imagePath in ImagePaths:
img = cv2.imread(imagePath)
# 图像灰度处理
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 将人脸用vector保存各个人脸的坐标、大小(用矩形表示)
faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)
for (x, y, w, h) in faces:
X = int(x * 1.0)
W = min(int((x + w) * 1.0), img.shape[1])
Y = int(y * 1.0)
H = min(int((y + h) * 1.0), img.shape[0])
f = cv2.resize(img[Y:H, X:W], (128, 128))
idnum, confidence = recognizer.predict(gray[y:y + h, x:x + w])
if confidence < 80:
namess = names[idnum]
confidence = "{0}%".format(round(100 - confidence))
cv2.imwrite(targetPath + os.sep + '%s' % namess + '%s' % confidence + '%s.jpg' % count, f)
count += 1
print(imagePath )
人脸拼接
def mark_pictures(self, SideLength, SideWide, type1):
heart_image = Image.new('RGB', (128 * SideLength, 128 * SideWide))
row = col = 0
for side in range(SideLength * SideWide):
if images_side_calc(col, row, type1):
img = Image.open(self.image_list.pop())
img = img.resize((128, 128), Image.ANTIALIAS)
else:
img = Image.new("RGB", (128, 128), (0, 0, 0))
heart_image.paste(img, (row * 128, col * 128))
col += 1
if col == SideWide:
col = 0
row += 1
if row == SideLength and col == SideWide:
break
heart_image.save("heart_image.jpg")
img = cv2.imread("heart_image.jpg")
cv2.namedWindow("Image", cv2.WINDOW_FREERATIO)
cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
部署
1.建立挂载目录
2.拉取镜像
docker pull adnrv/opencv:latest
pip list #查看该容器的库
- 代码用到的库cv2,os,csv,random,PIL,numpy。
3.开权限并运行
xhost +
docker run -it --privileged --rm --device=/dev/video0 -e DISPLAY=unix$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -v /home/lyh/face:/face adnrv/opencv bash
4.安装pillow库
pip3 install pillow
5.运行代码
(3)运行结果
运行界面
人脸录入
合照
FZU拼图
2020拼图
心形拼图
箭头拼图
(4)小组协作
学号 | 姓名 | 分工 | 贡献比 |
---|---|---|---|
031702234 | 林银河 | 人脸匹配识别,微服务部署 | 37% |
031702241 | 苏杰隆 | 人脸截取,微服务部署 | 33% |
031702236 | 王耀鑫 | 人脸拼接,微服务部署 | 30% |
(5)总结
王耀鑫
- 这次大作业,我们组尝试过树莓派的各种armv7镜像安装,这个属实恶心,装完某个库,接着导入会跟你说该库缺少某个包,补上这个包后又来一个,感觉像在填无底天坑,最后我们小组放弃树莓派,直接部署到虚拟机上。通过这次学习,我尝试了许多可能,加深了对树莓派,docker的理解,也粗粗涉猎了点人脸识别,增长了见识,深感自身能力薄弱,还需继续努力。
林银河
- 通过这次大作业,我对于opencv的使用有了一个更加深入的了解,简单了解了如何使用opencv进行人脸识别。我们遇到的最大的困难就是微服务的部署,原本我们小组准备采用树莓派实现,但是适合树莓派的armv7镜像是在是太少了,我们也尝试过自己搞一个符合要求的镜像,但是失败了,总是提示缺失文件,补了一个还有其他文件,最终我们放弃使用树莓派,转向了虚拟机,通过这次这使我对docker容器的部署有了更加深入的体会。我对于团队协作的重要意义也有了更深的理解。
苏杰隆
- 这次的大作业,本来是想在树莓派上运行代码的,用树莓派自带的摄像头实现人脸数据录入,而且在中期汇报时,代码部分已基本完成,本以为只要接下来在树莓派完成部署就可以说是大功告成,没想到部署过程一路坎坷。适合树莓派的armv7的镜像实在太少,想自行配一个镜像,从pypi找的轮子又屡屡出错,查阅官方文档方才得知另有专属树莓派的piwheel。从下完轮子之后先是contrib版本过高无法兼容,下载了正确版本后又在安装过程中缺失文件,缺失文件一个接一个,踩坑无数,此处省略百来篇我们所搜索的解决方案。。。最后不得不转战虚拟机,在虚拟机上实现项目。经历了树莓派的折磨,在虚拟机上已轻车熟路,感觉自己对docker的理解又上升了一个档次。但是由于大量时间花费在部署上,自己对代码并没有进行认真的研究,因此感觉对opencv的学习不够透彻,只有对opencv衍生的各种库产生了更多恐惧。好在队友之间能线上线下交流,一起攻克,解决了不少难题。