前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >人脸识别系统设计与实现:带有人脸关键点数据的处理方法

人脸识别系统设计与实现:带有人脸关键点数据的处理方法

作者头像
望月从良
发布于 2021-02-23 07:10:13
发布于 2021-02-23 07:10:13
6330
举报
文章被收录于专栏:Coding迪斯尼Coding迪斯尼

前面几个章节我们实现了用于PNet网络训练的若干种训练数据的生成办法。首先是构建了三种数据,分别为neg, part, pos,每种数据都是规格为12\*12的图片,其中第一种图片不包含人脸,或者人脸占据的比率不超过30,第二种包含部分人脸,其比率不超过45%,第三种包含人脸的比率超过了65%,这三种图片的目的由于训练网络识别出给定的图片内是否有人脸出现。

然而网络训练的目的不仅仅是要判断出图片中是否有人脸,而且还要能准确的找出人脸在图片中的准确位置,为了实现这点,算法还需要训练网络识别人脸五个关键点所在的坐标,这五个关键点分别对应两个眼睛,中间鼻子和两边嘴角,一旦网络能准确找到这五个关键点的坐标,说明网络能准确把握住人脸的根本特征。

由于PNet的能力是用于识别12*\12规格的图片中是否存在人脸,因此我们需要把图片缩放到给定规格后才能输入网络。这样就带来一个问题,那就是用于训练网络的相关数据会发生改变,例如在原图中,左眼所在坐标是(100,150),然后经过缩放后坐标自然会发生改变,而且在处理图片时,为了增强训练效果,我们还会对图片进行旋转,翻转等操作,于是原来给定关键点数据坐标也会发生改变。

处理这种情况的做法是,将具体坐标转换为相对位置的偏移。例如假设原图大小为100\*100,左眼坐标为(100,150),那么我们计算该坐标相对于图片左上角的偏移比率,于是左眼x坐标相对偏移比率是100/200=0.5, y坐标相对偏移比率是150/200 = 0.75,于是左眼坐标转换为(0.5, 0.75),于是当该图片缩放为规格12\*12后,我们可以很容易恢复出缩放后左眼坐标,那就是(12*0.5, 12*0.75)=(6,0.765),因此通过计算相对偏移比率,我们可以避免训练数据在图片经过转换后产生的错误,下面就是实现计算坐标偏移比率的代码:

```

class BBox:

def __init__(self, box):#box是人脸区域

self.left = box[0]

self.top = box[1]

self.right = box[2]

self.bottom = box[3]

self.x = box[0]

self.y = box[1]

self.w = box[2] - box[0]

self.h = box[3] - box[1]

def project(self, point):

#point对应人脸区域内的一点,要将它的绝对坐标转换为相对于左上角的偏移比率

x = (point[0] - self.x) / self.w

y = (point[1] - self.y) / self.h

return np.asarray([x,y])

def reproject(self, point):

#将相对偏移比率改为绝对坐标值

x = self.x + self.w * point[0]

y = self.y + self.h * point[1]

return np.asarray([x,y])

def reprojectLandmark(self, landmark):

#将特征点对应的偏移比率转为绝对坐标值

p = np.zeros((len(landmark), 2))

for i in range(len(landmark)):

p[i] = self.reproject(landmark[i])

return p

def projectLandmark(self, landmark):

#将特征点对应的坐标值改为相对偏移比率

p = np.zeros((len(landmark), 2))

for i in range(len(landmark)):

p[i] = self.project(landmark[i])

return p

```

接下来我们就需要针对特定的训练数据集做相关操作。在人脸识别应用中,最常用的数据集叫LFW,前面章节我们也提到过,其下载链接为:

链接: https://pan.baidu.com/s/1ODdzlMM_t_36-ldVOl7ySg 密码: f2cq

从链接下载数据解压后可以发现,它除了包含很多人脸图片外,还包含了一个非常重要的说明文件叫trainImageList.txt,该文件包含了图片数据的重要说明,其中的一些记录条目如下:

```

lfw_5590\Aaron_Eckhart_0001.jpg 84 161 92 169 106.250000 107.750000 146.750000 112.250000 125.250000 142.750000 105.250000 157.750000 139.750000 161.750000

```

上面是一个记录的内容,可以看到信息可以通过空格分隔开。其中第一个空格前面的信息也就是“lfw_5590\Aaron_Eckhart_0001.jpg”它对应的就是图片目录和名称,接下来四个数据“84 161 92 169”对应的是图片中人脸的左上角和右下角坐标,这四个数据就是我们需要进行偏移比率计算的对象,最后是10个数据“106.250000 107.750000 146.750000 112.250000 125.250000 142.750000 105.250000 157.750000 139.750000 161.750000”,其中每两个数据为一组,对应的就是一个关键点的坐标,后面我们需要训练网络能在读取人脸图片后,将这些关键点坐标计算出来。

根据一条记录的组成特点,我们实现下面函数用于读取数据集对应的记录文件:

```

def getDataFromTxt(txt, data_path, with_landmark = True):

with open(txt, 'r') as f:

lines = f.readlines() #读取lwf数据集对应描述文件中的每一行

result = []

for line in lines:

line = line.strip()

components = line.split(' ')

img_path = os.path.join(data_path, components[0]).replace("\\", '/')

box = (components[1], components[3], components[2], components[4]) #人脸区域

box = [float(_) for _ in box]

box = list(map(int, box))

#print("getDataFromTxt->path:{}, box: {}".format(img_path, box))

if not with_landmark:

result.append((img_path, BBox(box)))

continue

landmark = np.zeros((5, 2)) #5个关键点坐标值

for index in range(5):

rv = (float(components[5+ 2*index]), float(components[5 + 2*index+1]))

landmark[index] = rv

result.append((img_path, BBox(box), landmark))

return result

```

上面函数从给定文件trainImageList.txt中读取出每条记录,然后根据记录的组成规律,分别读取图片,人脸的坐标,以及五个关键点坐标,接下来我们需要做得是,通过每条记录读取图片,将图片中的人脸专门截取出来形成一个单独的图片文件,然后将人脸坐标转换成偏移比率,同时也要讲五个关键点坐标转换成偏移比率,最后将截取出来的人脸图片所在路径,转换后的人脸坐标以及关键点坐标组成一条记录信息,然后将记录信息写到一个专门文件中,形成类似trainImageList.txt这样的特征说明文件,代码实现如下:

```

def gen_landmark_aug(size):

#总共分三种情况,size=12对应pnet,size == 24对应rnet,size == 48对应onet

argument = True

if size == 12:

net = 'PNet'

elif size == 24:

net = 'RNet'

elif size == 48:

net = 'ONet'

image_id = 0

data_dir = '/content/'

OUTPUT = os.path.join(data_dir, str(size))

if not os.path.exists(OUTPUT):

os.mkdir(OUTPUT)

dstdir = os.path.join(OUTPUT, 'train_%s_landmark_aug' % (net))

if not os.path.exists(dstdir):

os.mkdir(dstdir)

ftxt = os.path.join(data_dir, "trainImageList.txt") #读取含有关键点数据的文档

f = open(os.path.join(OUTPUT, 'landmark_%d_aug.txt'%(size)), 'w')

data = getDataFromTxt(ftxt, data_dir)

idx = 0

for (img_path, box, landmarkGt) in tqdm(data):

F_imgs = []

F_landmarks = []

img = cv2.imread(img_path)

img_h, img_w, img_c = img.shape

gt_box = np.array([box.left, box.top, box.right, box.bottom])

try:

f_face = img[box.top:box.bottom+1, box.left:box.right+1, :] #将人脸截取出来

f_face = cv2.resize(f_face, (size, size), interpolation = cv2.INTER_LINEAR) #伸缩成给定大小,此时原来关键点坐标会失效,需要使用相对偏移

except Exception as e:

print("resize err with path: ", img_path)

print("resize err with shape: ", np.shape(img))

continue

landmark = np.zeros((5, 2))

for index, one in enumerate(landmarkGt):

rv = box.project(one) #注意这里的逻辑

landmark[index] = rv #这里获得关键点相对于人脸区域的偏移比例

F_imgs.append(f_face) #伸缩后的人脸

F_landmarks.append(landmark.reshape(10)) #关键点偏移比率

landmark = np.zeros((5, 2))

if argument: #这里会对人脸区域进行拉伸,旋转等变换,因此人脸区域和关键点也要在变换后重新计算

idx = idx + 1

x1, y1, x2, y2 = gt_box

gt_w = x2 - x1 + 1

gt_h = y2 - y1 + 1

if max(gt_w, gt_h) < 40 or x1 < 0 or y1 < 0: #忽略尺寸太小的人脸

continue

for i in range(20):

'''

根据人脸区域随机裁剪,其做法与前面获取neg, pos, part等图像的方法是一样的

'''

box_size = npr.randint(int(min(gt_w, gt_h)*0.8), np.ceil(1.25 * max(gt_w, gt_h)))

delta_x = npr.randint(-gt_w * 0.2, gt_h * 0.2)

delta_y = npr.randint(-gt_h * 0.2, gt_h * 0.2)

nx1 = int(max(x1 + gt_w /2 - box_size / 2 + delta_x, 0))

ny1 = int(max(y1 + gt_h / 2 - box_size / 2 + delta_y, 0))

nx2 = nx1 + box_size

ny2 = nx2 + box_size

if nx2 > img_w or ny2 > img_h:

continue

crop_box = np.array([nx1, ny1, nx2, ny2])

cropped_im = img[ny1:ny2+1, nx1:nx2+1, :]

try:

resized_im = cv2.resize(cropped_im, (size, size), interpolation = cv2.INTER_LINEAR)

except Exception as e:

print("resize error with resized_im shape: ", np.shape(resized_im))

print("resize error with cropped_im shape: ", np.shape(cropped_im))

print("resize error for size: ", nx1, ny1, nx2, ny2)

return

iou = IOU(crop_box, np.expand_dims(gt_box, 0))

if iou > 0.65: #如果区域含有人脸

print("crop pos face")

F_imgs.append(resized_im)

for index, one in enumerate(landmarkGt):

box = BBox([nx1, ny1, nx2, ny2])

landmark[index] = box.project(one)

F_landmarks.append(landmark.reshape(10))

landmark = np.zeros((5,2))

landmark_ = F_landmarks[-1].reshape(-1, 2)

box = BBox([nx1, ny1, nx2, ny2])

if random.choice([0,1]) > 0:

face_flipped, landmark_flipped = flip(resized_im, landmark_) #翻转操作

face_flipped = cv2.resize(face_flipped, (size, size), interpolation = cv2.INTER_LINEAR)

F_imgs.append(face_flipped)

F_landmarks.append(landmark_flipped.reshape(10))

print("flip landmark: ", landmark_flipped)

if random.choice([0,1]) > 0: #旋转和翻转操作

#逆时针旋转

face_rotated_by_alpha, landmark_rotated = rotate(img, box, box.reprojectLandmark(landmark_), 5)

landmark_rotated = box.projectLandmark(landmark_rotated)

print("rotate 5 landmark: ", landmark_rotated)

face_rotated_by_alpha = cv2.resize(face_rotated_by_alpha, (size, size), interpolation = cv2.INTER_LINEAR) #注意到由于关键点坐标转换成了相对于左上角的偏移比率,因此人脸图像缩放不会影响关键点坐标比率

F_imgs.append(face_rotated_by_alpha)

F_landmarks.append(landmark_rotated.reshape(10))

#对旋转后的人脸接着做左右翻转

face_flipped, landmark_flipped = flip(face_rotated_by_alpha, landmark_rotated)

face_flipped = cv2.resize(face_flipped, (size, size), interpolation = cv2.INTER_LINEAR)

F_imgs.append(face_flipped)

F_landmarks.append(landmark_flipped.reshape(10))

if random.choice([0, 1]) > 0: #顺时针翻转

face_rotated_by_alpha, landmark_rotated = rotate(img, box, box.reprojectLandmark(landmark_), -5)

landmark_rotated = box.projectLandmark(landmark_rotated)

print("rotate -5 landmark: ", landmark_rotated)

face_rotated_by_alpha = cv2.resize(face_rotated_by_alpha, (size, size), interpolation = cv2.INTER_LINEAR)

F_imgs.append(face_rotated_by_alpha)

F_landmarks.append(landmark_rotated.reshape(10))

#在顺时针翻转的图像基础上再进行左右翻转

face_flipped, landmark_flipped = flip(face_rotated_by_alpha, landmark_rotated)

face_flipped = cv2.resize(face_flipped, (size, size), interpolation = cv2.INTER_LINEAR)

F_imgs.append(face_flipped)

F_landmarks.append(landmark_flipped.reshape(10))

F_imgs, F_landmarks = np.asarray(F_imgs), np.asarray(F_landmarks)

for i in range(len(F_imgs)):

'''

数据清理,将那些关键点偏移比率小于0或者大于1的数据排除掉,产生这种情况时往往

是原来数据有问题

'''

if np.sum(np.where(F_landmarks[i] <= 0, 1, 0)) > 0:

print("landmark <= 0: ", F_landmarks[i])

continue

if np.sum(np.where(np.where(F_landmarks[i] >= 1, 1, 0))) > 0:

print("landmark >= 1: ", F_landmarks[i])

continue

#将旋转和翻转后的人脸数据写成文件

cv2.imwrite(os.path.join(dstdir, '%d.jpg'%(image_id)), F_imgs[i])

landmarks = list(map(str, list(F_landmarks[i])))

print("write landmark to file")

#将人脸图像的路径和对应的关键点坐标写入到文件中

f.write(os.path.join(dstdir, '%d.jpg' % (image_id)) + ' -2 ' + ' '.join(landmarks) + '\n')

image_id += 1

f.close()

return F_imgs, F_landmarks

```

经过上面处理以及前面章节描述的数据处理,现在我们总共有了4个数据说明文件,分别是neg_12.txt,其中记录了不包含人脸或人脸占比小于30%的图片目录,part_12.txt,其中记录了包含人脸比率不超过45%的图片位置,最后是pos_12.txt,其中记录了人脸比率超过65%的图片目录,最后是landmark_12_aug.txt,其中包含了人脸图片路径以及人脸坐标偏移比率和关键点坐标偏移比率,接下来我们要把四个文件的内容合成一个文件:

```

pos_save_dir = "/content/drive/MyDrive/my_mtcnn/12/positive/pos_12.txt"

part_save_dir = "/content/drive/MyDrive/my_mtcnn/12/part/part_12.txt"

neg_save_dir = "/content/drive/MyDrive/my_mtcnn/12/neg/neg_12.txt"

landmark_file_dir = '/content/12/landmark_12_aug.txt'

data_dir = '/content/drive/MyDrive/my_mtcnn/data'

def combine_files():

size = 12

with open(pos_save_dir, 'r') as f:

pos = f.readlines()

with open(part_save_dir, 'r') as f:

part = f.readlines()

with open(neg_save_dir, 'r') as f:

neg = f.readlines()

with open(landmark_file_dir, 'r') as f:

landmark = f.readlines()

if not os.path.exists(data_dir):

os.makedir(data_dir)

with open(os.path.join(data_dir, 'train_pnent_landmark.txt'), 'w') as f:

nums = [len(neg), len(pos), len(part)]

base_num = 250000

print('neg count:{}, pos count:{}, part cont:{}, base_num: {}'.format(len(neg),

len(pos), len(part), base_num))

if len(neg) > base_num * 3:

neg_keep = npr.choice(len(neg), size = base_num * 3, replace = True)

else:

neg_keep = npr.choice(len(neg), size = len(neg), replace = True)

sum_p = len(neg_keep) // 3

pos_keep = npr.choice(len(pos), sum_p, replace = True)

part_keep = npr.choice(len(part), sum_p, replace = True)

print('neg count:{}, pos count:{}, part cont:{}'.format(len(neg_keep), len(pos_keep), len(part_keep)))

for i in pos_keep:

f.write(pos[i])

for i in neg_keep:

f.write(neg[i])

for i in part_keep:

f.write(part[i])

for i in landmark:

f.write(i)

combine_files()

```

以上就是本节的基本内容,不得不承认,这几节关于训练数据处理的内容稍显枯燥和无聊,在深度学习算法应用的项目中,80%的工作内容都有关于训练数据的预处理。到这里有关数据处理的工作依然没有完成,下一节我们需要将这几节处理的数据转换成Tensorflow训练框架下特定的数据结构TFRecord。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coding迪斯尼 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
人脸识别系统设计实践:代码生成训练PNET的图片数据
上一节我们了解了PNET的基本原理,本节看看如何生成PNET需要的训练数据。总体而言我们需要产生两部分数据,一部分图片里面包含人脸,另一部分不包含人脸。这里的“包含”或“不包含”并不是指图片中完全没有人脸,而是图片中人脸占据的比率超过一定的阈值时就可以认为给定图片包含人脸。
望月从良
2021/01/04
5130
人脸识别系统设计实践:代码生成训练PNET的图片数据
人脸检测——mtcnn思想,生成negative、positive、part样本。
摘要总结:本文研究了面部识别技术,详细阐述了其基本原理、发展历程、应用领域以及未来前景。
MachineLP
2018/01/09
1.3K0
人脸识别系统的原理与实现:PNET训练数据预处理2
上一节我们详细说明了如何为PNET生成用于训练的人脸图片,本节我们需要将上一节分割出的人脸图片存储成文件,相关代码如下:
望月从良
2021/01/02
6570
人脸识别系统的原理与实现:PNET训练数据预处理2
MTCNN算法与代码理解—人脸检测和人脸对齐联合学习
主页:https://kpzhang93.github.io/MTCNN_face_detection_alignment/index.html 论文:https://arxiv.org/abs/1604.02878 代码:官方matlab版、C++ caffe版 第三方训练代码:tensorflow、mxnet
李拜六不开鑫
2018/12/26
2.3K0
基于 OpenCV 和 Dlib 头部姿态评估简单Demo
庐山烟雨浙江潮,未到千般恨不消。到得还来别无事,庐山烟雨浙江潮。 ----《庐山烟雨浙江潮》苏轼
山河已无恙
2023/08/21
7220
基于 OpenCV 和 Dlib 头部姿态评估简单Demo
使用这个 Python 库,只需一行命令,给头像戴上口罩!
2019 年底开始蔓延的新型肺炎疫情牵动人心,作为个体,我们力所能及的就是尽量待在家中少出门。
Python猫
2020/02/19
5230
用 dlib 计算人脸68个关键点
dlib 是较流行的人脸识别的开源库,使用c++编写,里面包含了许多的机器学习算法,。其官网链接是 dlib C++ Library - Machine Learning
用户6021899
2022/11/18
1.9K0
用 dlib 计算人脸68个关键点
基于Dlib的人脸检测与识别
人脸数:1 第 1 个人脸d的坐标:left: 201 right: 356 top: 184 bottom: 339 人脸面积为:24025
裴来凡
2022/05/29
6630
基于Dlib的人脸检测与识别
人脸识别原理详解:使用tfrecord集合网络训练所有数据
由于工作繁忙原因,对人脸识别技术原理的连载停了一段时间,从今天开始尝试恢复回来。我们先回想一下前面完成的工作。这几节主要任务就是为神经网络的训练准备足够多的数据,第一步是创建不包含或者包含人脸部分小于30%的图片,我们从人脸图片数据集中的每张图片随机选取一个矩形区域,确定该区域与人脸区域不重合或重合部分少于30%,这部分数据我们成为neg,目的是告诉网络没有人脸的图片是怎样的。
望月从良
2021/04/21
4920
Python使用dlib实现人脸检测
代码部分实现起来非常简单,不过十几行的事,不过需要注意的是,通过cv2.imread读取的图片是BRG通道的,需要转成RGB通道,不然通过pyplot显示图片会变色。
Awesome_Tang
2019/02/25
1.1K0
Python使用dlib实现人脸检测
人脸识别系列二 | FisherFace,LBPH算法及Dlib人脸检测
前面介绍了使用特征脸法进行人脸识别,这里介绍一下OpenCV人脸识别的另外两种算法,一种是FisherFace算法,一种是LBPH算法。
BBuf
2019/12/09
3.3K0
关于OpenCV for Python入门-dlib实现人脸检测
Dlib 是用编程语言 C ++编写的通用跨平台软件库。它的设计深受来自契约式设计和基于组件的软件工程的思想的影响。因此,首先也是最重要的是一组独立的软件组件。这是一个加速软件许可证下发布的开源软件。
python与大数据分析
2022/05/19
5340
关于OpenCV for Python入门-dlib实现人脸检测
Dlib 库 - 人脸检测及人脸关键点检测
Dlib 是一个十分优秀好用的机器学习库,其源码均由 C++ 实现,并提供了 Python 接口,可广泛适用于很多场景.
AIHGF
2019/03/11
15K0
Dlib 库 - 人脸检测及人脸关键点检测
PaddlePaddle实现人脸识别系统一——人脸数据集的获取
开发人脸识别系统,人脸数据集是必须的。所以在我们开发这套人脸识别系统的准备工作就是获取人脸数据集。本章将从公开的数据集到自制人脸数据集介绍,为我们之后开发人脸识别系统做好准备。
夜雨飘零
2020/05/01
3.6K0
人脸识别应用之“变脸”
“照片分享”是社交场景中比重很大的一部分,当然现在来看视频(特别是短视频)也变得越来越多,而照片又以人像为主,所以我们看到如QQ空间、微博、微信朋友圈里,自拍、合影占据着大量的版面。人脸相关的应用也越来越多:如相机中嵌入人脸检测,拍照时实时将人脸标注出来;又比如一些相册应用,能根据人脸识别进行照片分类;再比如支付宝的扫脸登录,将人脸作为个人身份ID。 这些应用都以人脸检测、人脸识别技术为基础,检测指将人脸定位出来,找到人脸所在位置,而识别则是匹配出这个人脸是谁,不过通常我们将这两项技术统称为人脸识别。随着深
智能算法
2018/04/02
3.8K0
人脸识别应用之“变脸”
基于MTCNN和MobileFaceNet实现的人脸识别
本教程是教程是介绍如何使用Tensorflow实现的MTCNN和MobileFaceNet实现的人脸识别,并不介绍如何训练模型。关于如何训练MTCNN和MobileFaceNet,请阅读这两篇教程 MTCNN-Tensorflow 和 MobileFaceNet_TF ,这两个模型都是比较轻量的模型,所以就算这两个模型在CPU环境下也有比较好的预测速度,众所周知,笔者比较喜欢轻量级的模型,如何让我从准确率和预测速度上选择,我会更倾向于速度,因本人主要是研究深度学习在移动设备等嵌入式设备上的的部署。好了,下面就来介绍如何实现这两个模型实现三种人脸识别,使用路径进行人脸注册和人脸识别,使用摄像头实现人脸注册和人脸识别,通过HTTP实现人脸注册和人脸识别。
夜雨飘零
2020/07/19
2.8K1
人脸检测——滑动窗口篇(训练和实现)
该文章介绍了如何使用深度学习实现人脸检测和识别。首先介绍了基于深度学习的人脸检测技术,包括基于Haar特征的级联分类器、Dlib库、人脸检测框架等。然后介绍了基于深度学习的人脸识别技术,包括DeepFace、FaceNet、ArcFace等。最后介绍了如何基于深度学习实现人脸检测和识别的应用,包括人脸门禁、人脸签到、人脸支付等。
MachineLP
2018/01/09
2.3K0
人脸检测——滑动窗口篇(训练和实现)
Dlib检测人脸68个特征,使用sklearn基于svm训练人脸微笑识别模型
使用Dlib提取人脸特征并训练二类分类器 (smile, nosmile) 来识别人脸微笑表情。
AnieaLanie
2021/12/12
3.8K1
MediaPipe实现手指关键点检测及追踪,人脸识别及追踪
OpenCV 是一个用于计算机视觉应用程序的库。在 OpenCV 的帮助下,我们可以构建大量实时运行更好的应用程序。主要用于图像和视频处理。
润森
2022/09/22
1.9K0
MediaPipe实现手指关键点检测及追踪,人脸识别及追踪
OpenCV实现人脸检测和68点定位
考虑到免费开源,OpenCV 就可以很好的实现这个功能。 这里使用OpenCV提供好的人脸分类模型xml:haarcascade_frontalface_alt_tree.xml。 同时利用Dlib官方给的人脸识别预测器“shape_predictor_68_face_landmarks.dat”进行68点标定(利用OpenCV进行图像化处理,在人脸上画出68个点,并标明序号)。
荣仔_最靓的仔
2021/02/02
4.8K1
OpenCV实现人脸检测和68点定位
推荐阅读
相关推荐
人脸识别系统设计实践:代码生成训练PNET的图片数据
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档