• Stars
    star
    915
  • Rank 48,846 (Top 1.0 %)
  • Language
    Python
  • License
    Other
  • Created about 4 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

【教程】从零开始的自制Vtuber!

从零开始的自制Vtuber: 1.面部捕捉初级

这是一个自制Vtuber的教程,这个教程包含从面部捕捉到图形渲染的一条龙服务。

这个教程是迭代式的,因此每当你看完一节时都可以做出一个Vtuber,它会随着你的学习而越发强大。

也许你能从中学到很多知识,但请不要跟着这个教程做,因为我有一些操作过于神奇以至于成了反面教材。

在第一节里,我们将会简单地体验一下面部捕捉技术,然后用一些数学计算追踪头部的角度,最后用一个简单的角色来展示今天的成果。

目录

  1. 面部捕捉初级 (就是这个文件所以没有链接)
  2. 画图和绘图
  3. 进入虚空 (从这里开始命名开始放飞自我了)
  4. 合成进化
  5. 一时休战
  6. 与神之假身的接触 (现在还是草稿)
  7. 还没写! (你以为有链接所以这真是个章节但实际上不是)
  8. 真的还没写! (没想到还没写居然会多出一个吧!)

警告

这个章节还没有完成校订,因此可能有和谐内容。

请您收好鸡儿,文明观球。

准备

在这个章节,你需要准备:

  • 电脑
  • 摄像头
  • 基本的图形图像概念
  • 高中的计算几何知识
  • Python3
  • Dlib
  • OpenCV
  • NumPy

明明是从零开始却用了好多库!

事情是这样的,根据皮亚诺公理,凡是你认为是0的东西就是0。

读取视频流

首先我们使用OpenCV从摄像头读取视频流,并尝试着把它播放在窗口上。

cap = cv2.VideoCapture(0)
while True:
    ret, img = cap.read()
    img = cv2.flip(img, 1)
    cv2.imshow('self', img)
    cv2.waitKey(1)

OpenCV 4.4.0.40 会出现 Segment fault when call imshow 的错误,最好使用其他版本。

cv2.VideoCapture(0)表示默认摄像头,如果用外置摄像头可能得把它改成1。

cv2.flip的作用是把帧左右翻转,使你看起来像在照镜子一样。

./图/1-1.jpg

完成之后,你应当会获得一个这样的窗口。
如果你的窗口里的人和长得和上面的不一样,这是正常的。

提取面部关键点

接下来我们将使用Dlib提取面部关键点。因为Dlib挺好用的,所以我们暂时不用去想它是怎么做到的。

在这之前,我们得先确保img中至少有一张人脸,并找到最大的那张脸。

之所以要这么做并不是为了防止萝莉在旁边捣乱(她的脸比较小),而是防止有时把环境里某些看起来像人头的小物件识别成脸而引起面部捕捉的错误。

detector = dlib.get_frontal_face_detector()
def 人脸定位(img):
    dets = detector(img, 0)
    if not dets:
        return None
    return max(dets, key=lambda det: (det.right() - det.left()) * (det.bottom() - det.top()))

(代码逐渐缺德2333)

接下来,我们就可以对刚才找到的脸位置提取关键点了。为了让接下来的向量运算方便一些,你可以考虑把他们通通转换成np.array

如果你没有shape_predictor_68_face_landmarks.dat,可以去 GitHubdlib 下载。

predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
def 提取关键点(img, 脸位置):
    landmark_shape = predictor(img, 脸位置)
    关键点 = []
    for i in range(68):
        pos = landmark_shape.part(i)
        关键点.append(np.array([pos.x, pos.y], dtype=np.float32))
    return 关键点

接下来试着把这些关键点在你的摄像头画面上绘制出来——

for i, (px, py) in enumerate(关键点):
    cv2.putText(img, str(i), (int(px), int(py)), cv2.FONT_HERSHEY_COMPLEX, 0.25, (255, 255, 255))

./图/1-2.jpg

如果一切正确的话,你的窗口将会像上面这样,有种戴上了奇怪的面具的感觉。

计算面部特征

第一天我们先来试着提取一点简单的特征吧,就做「头的左右旋转」好了。

这个原理非常简单以至于我们可以用手来实现它。
我们知道,越远离旋转轴的点,受到旋转的影响就越大,也就是说,我把头向左转的时候,尽管我的眉毛和鼻子都向左移动了,但是鼻子一定在比眉毛还左的左边。

接下来我们根据关键点计算一下它们的座标,就可以计算出旋转角度了。

def 生成构造点(关键点):
    def 中心(索引数组):
        return sum([关键点[i] for i in 索引数组]) / len(索引数组)
    左眉 = [18, 19, 20, 21]
    右眉 = [22, 23, 24, 25]
    下巴 = [6, 7, 8, 9, 10]
    鼻子 = [29, 30]
    return 中心(左眉 + 右眉), 中心(下巴), 中心(鼻子)

你可以模仿上面画关键点的代码在图上把它们画出来,它们应该长这样——

./图/1-3.jpg

可以看出眉中心 下巴中心 鼻子中心组成了一个三角形,我们希望能从这个三角形里提取出一些有用的特征。而且因为各种不同的摄像头的画面大小都不太一样,最好这些特征都具有缩放不变性。

这个三角形的形状是和脸部的角度有关的。三角形越是瘦长,脸部就越是中正。因此你只要用一点向量知识来计算它的胖瘦就可以得到脸部的旋转量。

任意两条边做叉乘就能得到三角形的有向面积,除以底边长就能得到对应底边上的有向高,再除一次底边得到的就是高与底的比值了。

def 生成特征(构造点):
    眉中心, 下巴中心, 鼻子中心 = 构造点
    中线 = 眉中心 - 下巴中心
    斜边 = 眉中心 - 鼻子中心
    横旋转量 = np.cross(中线, 斜边) / np.linalg.norm(中线)**2
    return 横旋转量

我没有用到三角函数,这是因为我们的检测器没法检测太大的角度,而sin(x)在原点附近的导数几乎是1,所以这样就够了。

把旋转量画在鼻子上,它看起来是这样——

./图/1-4-1.jpg ./图/1-4-2.jpg

如果你觉得只有这样的左右旋转看起来有点无聊,我们也可以再来添加一个检测一个上下旋转的特征。

它的数学表达式和刚才的横旋转量很接近,你们可能已经猜出来了,这个特征只需要求斜边在底边上的投影长度与底边长的比值——

横旋转量 = np.cross(中线, 斜边) / np.linalg.norm(中线)**2
竖旋转量 = 中线 @ 斜边 / np.linalg.norm(中线)**2

如果你用起来的效果很差,说明你的鼻子太扁了,你可以考虑整容来解决这个问题。

添加标准脸

你肯定发现了这样一个问题,我们刚才检测了横旋转量竖旋转量,可是因为普通人的脸是左右对称的,不是上下对称的,所以正对镜头时的竖旋转量并不是0。

为了解决这个问题,我们可以给竖旋转量减去固定一个数值,不过更好的方法是添加一个标准脸图片。
你只要正对镜头的时候拍个照,把它的特征保存下来作为一个相对的原点,之后把每次新检测到的特征减去原点就行了。

原点特征组 = 提取图片特征(cv2.imread('std_face.jpg'))
while True:
    ret, img = cap.read()
    新特征组 = 提取图片特征(img)
    if 新特征组 is not None: 
        特征组 = 新特征组 - 原点特征组

绘图

现在我们马上就要做出第一个会动的Vtuber了,因为画画很麻烦所以先用圆圈凑合一下。

只要画上几个圈圈,让它们的座标取决于脸部的旋转量,这张圆圈脸看起来就好像跟着人脸在旋转一样——

def 画图(横旋转量, 竖旋转量):
    img = np.ones([512, 512], dtype=np.float32)
    脸长 = 200
    中心 = 256, 256
    左眼 = int(220 + 横旋转量 * 脸长), int(249 + 竖旋转量 * 脸长)
    右眼 = int(292 + 横旋转量 * 脸长), int(249 + 竖旋转量 * 脸长)
     = int(256 + 横旋转量 * 脸长 / 2), int(310 + 竖旋转量 * 脸长 / 2)
    cv2.circle(img, 中心, 100, 0, 1)
    cv2.circle(img, 左眼, 15, 0, 1)
    cv2.circle(img, 右眼, 15, 0, 1)
    cv2.circle(img, , 5, 0, 1)
    return img

./图/1-5.jpg

这一节就到此为止了……这东西真的能叫Vtuber吗(笑)

这样吧,下一节我们先来画一张立绘。
只要让真正的立绘动起来,就能做出一个可爱的Vtuber。

结束

如果我的某些操作让你非常迷惑,你也可以去这个项目的GitHub仓库查看源代码。

最后祝各位鸡儿放假。

下一节:

More Repositories

1

match-you

【您配吗】配你吗
JavaScript
1,448
star
2

unvcode

【幼女Code】反和谐超级武器!
Python
1,070
star
3

Librian

【Librian】簡明強大的 Galgame | Visual Novel 引擎
Python
652
star
4

yinglish

【yinglish】淫语翻译机!
Python
517
star
5

sese-engine

【sese-engine】新时代的搜索引擎!
Python
480
star
6

steal_piano

【steal piano】GitHub偷情分析工具!
Python
463
star
7

Night-Beam

【Night Beam】去除文本马赛克的随机算法!
Python
206
star
8

internet-dataset

【数据集】好耶,是互联网数据集!
168
star
9

kill3d

三次元人类屏蔽器!
Python
167
star
10

color_site

【色圖網站】
HTML
144
star
11

unv-shield

【幼盾】个性化图片徽章服务!
Python
141
star
12

bnhhsh

【不能好好说话】不对劲的拼音首字母缩写翻译工具
Python
103
star
13

modnet-entry

【MODNet-entry】开箱即用的人像抠图工具
Python
100
star
14

not_translator

【not translator】不会翻译机!
Python
79
star
15

cotrace

【cotrace】同事追踪器!
Python
73
star
16

thyrune

你的纪念碑!
Python
72
star
17

librian-can

【轻小说连载】Librian萝莉会所!
57
star
18

minecraft

用Python-OpenGL实现的minecraft
Python
53
star
19

loliimg

【萝莉图片算法】高损图像压缩算法!?
Python
52
star
20

smoke_of_deceit

把代码藏起来!
50
star
21

python-anti-seduce-system

针对Python语言防沉迷调整的说明
Python
49
star
22

ciallo

【ciallo】别他妈了隔壁念你那通稿
JavaScript
44
star
23

rimochan

莉沫酱GitHub展板
Python
44
star
24

...

【萝莉病毒?】删不掉的..!
Pascal
42
star
25

rimo-rss-reader

【rimo-rss-reader】莉沫酱RSS阅读器!
Python
40
star
26

Je-Suis-Le-Deluge

莉沫酱革命协议!
40
star
27

i7h

【i18nglish】自动i18n!
Python
35
star
28

hoshi

【星】pdf扫描件 转 docx
Python
34
star
29

water-generator

这次是真的发水机!
34
star
30

chao

【超】Python魔法加速器!
Python
33
star
31

rime-unvcode

幼⼥输⼊法!
33
star
32

raspberry-pi-bedroom-monitor

基于树莓派的多功能寝室监控系统
Python
32
star
33

rimochan-LORA

【rimochan-LORA】量产型电子莉沫酱!
32
star
34

rimochan-cookbook

莉沫酱小本子!
32
star
35

flowerpot

不用浇水的花盆!
30
star
36

kokoro

这次是可可萝病毒!
Python
30
star
37

lunar-Ci

【lunar-Ci】今日诸事不宜!
Python
27
star
38

Rimo-Kitchen

莉沫酱小厨房!
27
star
39

unvdisco

【幼女盘】网盘界文艺复兴!
Python
24
star
40

changgelog

【唱歌log】让你的程序学会唱歌!
Python
22
star
41

GPT-reader

【GPT-reader】让GPT帮你读小说吧!
Python
21
star
42

Invoker

【Invoker】word2vec的智能記單詞app
Python
21
star
43

True-tool

【真具】真正的CG包去重壓縮工具
Python
20
star
44

PSO-image-match

神奇的粒子群图像匹配! Particle Swarm Optimization(PSO) image template matching
Python
20
star
45

inherit

【教程】莉沫酱教你学继承!?
Python
17
star
46

child-lock

【child-lock】儿童锁!
Python
15
star
47

dota2-card

【dota2卡】老子不上班了!
Python
14
star
48

Cinder

烤肉识别器!
Python
13
star
49

Lunatic_red_eyes

【幻朧月睨】催眠調教的app!
Python
11
star
50

rimo-lab

莉沫酱人体实验室!
11
star
51

my_2dkf_css

我在緋月論壇用的CSS
Sass
10
star
52

paradox-mod-translator

P社mod翻译器!
Python
9
star
53

jiu_zi_qie

【九字切】背誦日文單詞!
Python
9
star
54

rimo_utils

莉沫工具箱
Python
9
star
55

hrml

【hrml】超莉沫酱自慰语言!
Python
9
star
56

negate_hypnotic

抗催眠装置!
Python
9
star
57

hw

黄巍机器人!
Python
8
star
58

conception-license

绝对遵守☆强制子作许可证
8
star
59

github-close-machine

GitHub快速取关机!
Python
8
star
60

copylot

【copylot】Photoshop的实时stable diffusion插件!
Python
8
star
61

unvqlo

【unvqlo】莉沫酱周边博物馆!
JavaScript
8
star
62

keras-ACG-face-alignment

【ACG-face-alignment】ACG臉部對齊
Python
8
star
63

readme-hack

【???】給github的readme添加css
CSS
7
star
64

rimo_storage

莉沫酱存储!
Python
7
star
65

yuri

这次是真的催眠调教器!
Python
7
star
66

sunder

心灵控制器!
Python
6
star
67

the-destiny-star-of-girlfriend

【宗教迷信】宿星的女朋友
6
star
68

Pepin

同事批评器!
Python
6
star
69

waifu-sensor

【老婆探测器】一个普通的动漫角色分类模型
Python
5
star
70

Mask-Translator

可重用的代碼翻譯器!
Python
4
star
71

synthetic-css

Synthetic風格CSS
Sass
4
star
72

not_view

【不看】不好的图片浏览器
Python
4
star
73

Gensho

【幻書】能編程的自然中文!
Python
4
star
74

stable-diffusion-anime-tag-benchmark

stable diffusion 动漫标签自动化评测
Python
4
star
75

snow

【雪】自用的编译运行工具
Python
3
star
76

Free4

放肆的解压算法!
Python
3
star
77

false_moon

【夜空珠】keras的深度圖像隱寫術!
Python
3
star
78

seal-sorcery

印刷术!
Python
3
star
79

LG-University

莆田理工大学文档
HTML
2
star
80

cm3d2-parser

3D定制女仆MOD解析器
Python
2
star
81

pmd

【pmd】python雜交cmd!
Python
2
star
82

vscode-rimo-theme

vscode主题
Sass
1
star
83

Qi

气象观测站!
1
star