一、Python所有方向的学习路线
Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、学习软件
工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。
三、入门学习视频
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
第二, 在嵌入基础上使用支持向量机(SVM)训练人脸识别模型。
第三,最后使用 OpenCV 识别图像和视频流中的人脸。
===============================================================
facedetection
├─dataset
│ ├─Biden
│ ├─chenglong
│ ├─mayun
│ ├─Trump
│ ├─yangmi
│ └─zhaoliying
├─face_dete_model
│ ├─deploy.proto.txt
│ └─res10_300x300_ssd_iter_140000_fp16.caffemodel
│
├─output
├─face_embeddings.py
├─nn4.small2.v1.t7
├─recognize_face.py
├─recognize_video.py
└─train_face.py
=============================================================
新建face_embeddings.py脚本,写入如下代码:
import the necessary packages
import numpy as np
import pickle
import cv2
import os
import os
导入需要的包。然后定义几个函数:
def list_images(basePath, contains=None):
return the set of files that are valid
return list_files(basePath, validExts=image_types, contains=contains)
def list_files(basePath, validExts=None, contains=None):
loop over the directory structure
for (rootDir, dirNames, filenames) in os.walk(basePath):
loop over the filenames in the current directory
for filename in filenames:
if the contains string is not none and the filename does not contain
the supplied string, then ignore the file
if contains is not None and filename.find(contains) == -1:
continue
determine the file extension of the current file
ext = filename[filename.rfind(“.”):].lower()
check to see if the file is an image and should be processed
if validExts is None or ext.endswith(validExts):
construct the path to the image and yield it
imagePath = os.path.join(rootDir, filename)
yield imagePath
def resize(image, width=None, height=None, inter=cv2.INTER_AREA):
dim = None
(h, w) = image.shape[:2]
如果高和宽为None则直接返回
if width is None and height is None:
return image
检查宽是否是None
if width is None:
计算高度的比例并并按照比例计算宽度
r = height / float(h)
dim = (int(w * r), height)
高为None
else:
计算宽度比例,并计算高度
r = width / float(w)
dim = (width, int(h * r))
resized = cv2.resize(image, dim, interpolation=inter)
return the resized image
return resized
list_images函数,读取数据集文件夹下面的图片。
resize函数,等比例resize图片。接下来定义一些变量:
dataset_path=‘dataset’
embeddings_path=‘output/embeddings.pickle’
detector_path=‘face_dete_model’
embedding_model=‘nn4.small2.v1.t7’
confidence_low=0.5
dataset_path:数据集路径
embeddings_path:输出编码文件的路径
detector_path:人脸检测模型的路径
embedding_model:编码模型
confidence_low:最低的置信度。
接下来就是代码的最重要的部分:
print(“loading face detector…”)
protoPath = os.path.sep.join([detector_path, “deploy.proto.txt”])
modelPath = os.path.sep.join([detector_path,“res10_300x300_ssd_iter_140000_fp16.caffemodel”])
detector = cv2.dnn.readNetFromCaffe(protoPath, modelPath)
加载序列化的人脸编码模型
print(“loading face recognizer…”)
embedder = cv2.dnn.readNetFromTorch(embedding_model)
获取数据集中输入图像的路径
print(“quantifying faces…”)
imagePaths = list(list_images(dataset_path))
初始化我们提取的面部编码列表和相应的人名
knownEmbeddings = []
knownNames = []
初始化处理的人脸总数
total = 0
loop over the image paths
for (i, imagePath) in enumerate(imagePaths):
extract the person name from the image path
print(“processing image {}/{}”.format(i + 1,len(imagePaths)))
name = imagePath.split(os.path.sep)[-2]
加载图像,将其调整为宽度为 600 像素(同时保持纵横比),然后抓取图像尺寸
image = cv2.imread(imagePath)
image = resize(image, width=600)
(h, w) = image.shape[:2]
从图像构建一个 blob
imageBlob = cv2.dnn.blobFromImage(
cv2.resize(image, (300, 300)), 1.0, (300, 300),
(104.0, 177.0, 123.0), swapRB=False, crop=False)
使用 OpenCV 的基于深度学习的人脸检测器来定位输入图像中的人脸
detector.setInput(imageBlob)
detections = detector.forward()
ensure at least one face was found
if len(detections) > 0:
假设每个图像只有一张脸,所以找到概率最大的边界框
i = np.argmax(detections[0, 0, :, 2])
confidence = detections[0, 0, i, 2]
确保最大概率的检测也意味着我们的最小概率测试(从而帮助过滤掉弱检测)
if confidence > confidence_low:
计算人脸边界框的 (x, y) 坐标
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype(“int”)
提取人脸ROI并抓取ROI维度
face = image[startY:endY, startX:endX]
(fH, fW) = face.shape[:2]
确保人脸宽度和高度足够大
if fW < 20 or fH < 20:
continue
为人脸 ROI 构造一个 blob,然后将 blob 通过我们的人脸嵌入模型来获得人脸的 128-d 量化
faceBlob = cv2.dnn.blobFromImage(face, 1.0 / 255,
(96, 96), (0, 0, 0), swapRB=True, crop=False)
embedder.setInput(faceBlob)
vec = embedder.forward()
将人名+对应的人脸嵌入添加到各自的列表中
knownNames.append(name)
knownEmbeddings.append(vec.flatten())
total += 1
保存编码文件
print(“serializing {} encodings…”.format(total))
data = {“embeddings”: knownEmbeddings, “names”: knownNames}
f = open(embeddings_path, “wb”)
f.write(pickle.dumps(data))
f.close()
加载人脸检测器和编码器:
检测器:使用基于Caffe的DL人脸检测器来定位图像中的人脸。
编码器:模型基于Torch,负责通过深度学习特征提取来提取人脸编码。
接下来,让我们抓取图像路径并执行初始化。
遍历 imagePaths。从路径中提取人名。
构造了一个 blob。
然后,通过将 imageBlob 通过检测器网络来检测图像中的人脸。
检测列表包含定位图像中人脸的概率和坐标。
假设我们至少有一个检测,将进入 if 语句的主体。
假设图像中只有一张脸,因此提取具有最高置信度的检测并检查以确保置信度满足用于过滤弱检测的最小概率阈值。
假设已经达到了这个阈值,提取面部 ROI 并抓取/检查尺寸以确保面部 ROI 足够大。
然后,我们将利用编码器 并提取人脸编码。
继续构建另一个 blob。
随后,将 faceBlob 通过编码器 。 这会生成一个 128 维向量 (vec) 来描述面部。
然后我们简单地将名称和嵌入 vec 分别添加到 knownNames 和 knownEmbeddings 中。
继续循环图像、检测人脸并为数据集中的每个图像提取人脸编码的过程。
循环结束后剩下的就是将数据转储到磁盘。
运行结果:
loading face detector…
loading face recognizer…
quantifying faces…
processing image 1/19
processing image 2/19
processing image 3/19
processing image 4/19
processing image 5/19
processing image 6/19
processing image 7/19
processing image 8/19
processing image 9/19
processing image 10/19
processing image 11/19
processing image 12/19
processing image 13/19
processing image 14/19
processing image 15/19
processing image 16/19
processing image 17/19
processing image 18/19
processing image 19/19
serializing 19 encodings…
Process finished with exit code 0
===================================================================
已经为每张脸提取了 128 维编码——但是我们如何根据这些嵌入来识别一个人呢?
答案是我们需要在嵌入之上训练一个“标准”机器学习模型(例如 SVM、k-NN 分类器、随机森林等)。
今天我们使用SVM实现
打开 train_face.py 文件并插入以下代码:
from sklearn.preprocessing import LabelEncoder
from sklearn.svm import SVC
import pickle
embeddings_path=‘output/embeddings.pickle’
recognizer_path=‘output/recognizer.pickle’
lable_path=‘output/le.pickle’
加载编码模型
print(“[INFO] loading face embeddings…”)
data = pickle.loads(open(embeddings_path, “rb”).read())
给label编码
print(“[INFO] encoding labels…”)
le = LabelEncoder()
labels = le.fit_transform(data[“names”])
训练用于接受人脸 128-d 嵌入的模型,然后产生实际的人脸识别
recognizer = SVC(C=1.0, kernel=“linear”, probability=True)
recognizer.fit(data[“embeddings”], labels)
保存模型
f = open(recognizer_path, “wb”)
f.write(pickle.dumps(recognizer))
f.close()
保存lable
f = open(lable_path, “wb”)
f.write(pickle.dumps(le))
f.close()
导入包和模块。 我们将使用 scikit-learn 的支持向量机 (SVM) 实现,这是一种常见的机器学习模型。
定义变量。
-
embeddings_path:序列化编码。
-
recognizer_path:这将是我们识别人脸的输出模型。 它基于 SVM。
-
lable_path:标签编码器输出文件路径
加载编码。
然后初始化 scikit-learn LabelEncoder 并编码名称标签。
训练模型。本文使用的是线性支持向量机 (SVM),但如果您愿意,您可以尝试使用其他机器学习模型进行试验。
训练模型后,我们将模型和标签编码器保存到电脑上。
运行train_face.py 脚本。
===================================================================
新建脚本文件recognize_face.py,插入一下代码:
import numpy as np
import pickle
import cv2
import os
导入包,然后我们需要新增一个resize方法。
def resize(image, width=None, height=None, inter=cv2.INTER_AREA):
dim = None
(h, w) = image.shape[:2]
如果高和宽为None则直接返回
if width is None and height is None:
return image
检查宽是否是None
if width is None:
计算高度的比例并并按照比例计算宽度
r = height / float(h)
dim = (int(w * r), height)
高为None
else:
计算宽度比例,并计算高度
r = width / float(w)
dim = (width, int(h * r))
resized = cv2.resize(image, dim, interpolation=inter)
return the resized image
return resized
等比例resize图像,定义变量:
image_path = ‘11.jpg’
detector_path = ‘face_dete_model’
embedding_path = ‘nn4.small2.v1.t7’
recognizer_path = ‘output/recognizer.pickle’
label_path = ‘output/le.pickle’
confidence_low = 0.5
这六个变量的含义如下:
-
image_path :输入图像的路径。
-
detector_path:OpenCV 深度学习人脸检测器的路径。 使用这个模型来检测人脸 ROI 在图像中的位置。
-
embedding_path : OpenCV 深度学习人脸编码模型的路径。 我们将使用这个模型从人脸 ROI 中提取 128 维人脸嵌入——然后将把数据输入到识别器中。
-
recognizer_path :识别器模型的路径。
-
label_path : 标签编码器的路径。
-
confidence_low:过滤弱人脸检测的可选阈值。
接下来是代码的主体部分:
加载序列化人脸检测器
print(“[INFO] loading face detector…”)
protoPath = os.path.sep.join([detector_path, “deploy.proto.txt”])
modelPath = os.path.sep.join([detector_path,“res10_300x300_ssd_iter_140000_fp16.caffemodel”])
detector = cv2.dnn.readNetFromCaffe(protoPath, modelPath)
加载我们序列化的人脸编码模型
print(“[INFO] loading face recognizer…”)
embedder = cv2.dnn.readNetFromTorch(embedding_path)
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!