半路出家,感觉简历上没啥可写,准备试着写一写功能型的代码!
首先我们要知道cv2中是有自带的很多分类器(我这边是17个)直接加载在代码里
classfier = cv2.CascadeClassifier("F:/Anaconda/Library/etc/haarcascades/haarcascade_frontalface_alt2")
首先打开摄像头,笔记本的自带摄像头一般index都是0;
window_name = 'face_finder'
cv2.namedWindow(window_name)
cap = cv2.VideoCapture(0)
然后因为我刚开始没找到这个分类器的目录,在编译的时候加了一个判断分类器有没有成功加载的error报告:
if classfier.empty():
raise IOError('Unable to load the face cascade classifier xml file')
我们先从视频中读取一帧:
while cap.isOpened():
re, frame = cap.read() #读取一帧数据
if not re:
break
然后就可以对应这一帧图像做人脸识别了。为了减少计算量,我们可以先转换图像为灰度图,再进行人脸识别:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faceRects = classfier.detectMultiScale(gray, scaleFactor = 1.5, minNeighbors = 3, minSize = (32, 32))
```
gray为输入图像;scaleFactor是缩放比例;
minNeighbors是对特征检测点周边多少有效点同时检测;
minSize是检测点的最小值。
```
if len(faceRects) > 0: #大于0则检测到人脸
for faceRect in faceRects: #单独框出每一张人脸
x, y, w, h = faceRect
cv2.rectangle(frame, (x - 5, y - 5), (x + w + 5, y + h + 5), color, 2)#留一个边边
然后就可以显示图像了,最后不要忘了释放
cv2.imshow(window_name, frame)
c = cv2.waitKey(10)
if c & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
至此,就可以实现把人脸和其他物体区分开了,这个图像中的框会跟随着脸移动。
这种方法是利用了opencv自带的分类器,所以代码特别简单。
不过这个程序现在对所有人脸都可以识别出来,但没办法分清楚谁是谁,准备弄一个类似之前一个日本程序员做的老板识别装置一样,只让这个程序识别出是/不是某个特定的人。当然这个功能不止有识别老板的功能,在手机面部解锁这方面应该也可以有应用。不过这个算法毕竟还比较低级,能识别的人数很有限(A/B/C/…/非A&非B&非C…),人数太多可能对神经网络的耗时也会有压力。
在前面的tensorflow(行文至此才发现tensorflow的部分我只写了mnist集(3.1),基本原理压根没细说,告罪,马上补上)中应该说到了,我们既然要训练神经网络,那就要让他有一个训练集。于是我们让这个程序采集我们的若干张图片:
cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 2)
img_name = '%s/%d.jpg'%("C:/Users/Administrator/.spyder-py3/video_facefinder/facedata_me", num)
image = frame[y - 10: y + h + 10, x - 10: x + w + 10]
cv2.imwrite(img_name, image)
num += 1
if num > (catch_pic_num):
break
这段代码插进上一段的相应位置,定义一下缺少的参数就行了。
我电脑比较弟弟,所以就只采了自己的1000张丑脸,其中混入了几张错误识别到的不明物体。如何删除掉呢?方法有很多,比如做颜色分析,平均值接近肤色的识别为脸,其他识别为杂项;比如做频率分析,看高频成分的量,来做区分;不过这些个参数要摸索,我一共1000个脸里就混进了个位数个不明物体,所以我就手动删了。。
然后要把这些个脸全部变成同样大小的图片,为了池化方便我们设置成64*64(随便设置的,whatever),长宽不同的补上黑边,这样缩放时不会让丑脸失真变得更丑。
import os
import sys
import numpy as np
import cv2
IMAGE_SIZE = 64
def resize_image(image, height = IMAGE_SIZE, width = IMAGE_SIZE):
top, bottom, left, right = (0, 0, 0, 0)
h, w, _ = image.shape
#在短边部分加上黑边,使之与长边等长
longest_edge = max(h, w)
if h < longest_edge:
dh = longest_edge - h
top = dh // 2
bottom = dh - top
elif w < longest_edge:
dw = longest_edge - w
left = dw // 2
right = dw - left
else:
pass
#RGB颜色
BLACK = [0, 0, 0]
constant = cv2.copyMakeBorder(image, top , bottom, left, right, cv2.BORDER_CONSTANT, value = BLACK)
return cv2.resize(constant, (height, width))
#读取训练数据
images = []
labels = []
def read_path(path_name):
for dir_item in os.listdir(path_name):
#从初始路径开始叠加,合并成可识别的操作路径
full_path = os.path.abspath(os.path.join(path_name, dir_item))
if os.path.isdir(full_path): #如果是文件夹,递归
read_path(full_path)
else: #是文件
if dir_item.endswith('.jpg'):
image = cv2.imread(full_path)
image = resize_image(image, IMAGE_SIZE, IMAGE_SIZE)
images.append(image)
labels.append(path_name)
return images,labels #加载数据集
#从指定路径读取训练数据
def load_dataset(path_name):
images,labels = read_path(path_name)
#将输入的所有图片转成四维数组,尺寸为(n*IMAGE_SIZE*IMAGE_SIZE*3)
images = np.array(images)
print(images.shape)
#标注数据,我的脸部图像全部指定为0,其他的全部指定为1
labels = np.array([0 if label.endswith('facedata_me') else 1 for label in labels])
return images, labels
if __name__ == '__main__':
if len(sys.argv) != 2:
print("Usage:%s path_name\r\n" % (sys.argv[0]))
else:
images, labels = load_dataset(sys.argv[1])
这样子就搞好数据集了。后面的步骤等我收集一下别人的大头照再说,溜了溜了。。
突然发现还有keras作为轻量级tensorflow接口,学习一哈,舒服了:
https://blog.csdn.net/zj360202/article/details/78646969(【Tensorflow keras】轻量级深度学习框架 Keras简介)
https://blog.csdn.net/liuuze5/article/details/79529880(使用 Keras + TensorFlow 开发一个复杂深度学习模型)
后面的明天再写,然后把我理解的图像处理+深度学习基础稍微总结一点,就酱。
下一篇:https://blog.csdn.net/dimei0938/article/details/82052702
基础知识:https://blog.csdn.net/dimei0938/article/details/82152617