飞桨,请给我来个表情

飞桨,请给我来个表情

  • 项目背景

在互联网飞速发展的时代,我们的交流方式不断地创新与迭代,这是不可逆转的趋势。我们正是这时代中的一员,以年轻的心,张扬个性。在平时生活中,线上聊天也必不可少。如何成为群里最靓的仔呢?可以试试飞桨,定制自己的专属表情!话不多说,先上效果图。图1
图2
图1为原图,图2为生成图

项目地址:

https://aistudio.baidu.com/aistudio/projectdetail/1517247

  • 项目算法简介

此项目使用了三个模型,分别为FastSpeech、Wav2Lip和HumanSeg。接下来,我们一起了解一下这些模型。

第一个模型:FastSpeech(文字转语音),它是一种高保真文字转语音的模型。本文中使用的是飞桨语音合成套件Parakeet中的FastSpeech,该模型中的声码器用的是百度研究提出的WaveFlow。相较于其它模型,WaveFlow更轻量、质量更高。

在这里插入图片描述

  • FastSpeech模型解析图

FastSpeech论文链接:

https://arxiv.org/abs/1905.09263
WaveFlow算法介绍链接:

https://arxiv.org/abs/1912.01219
Parakeet项目地址:

https://github.com/PaddlePaddle/Parakeet/tree/release/v0.1

第二个模型:Wav2Lip(唇形合成)。这是基于PaddleGAN(生成对抗网络)的一个模型,可以根据音频生成与音频同步的人物唇形,使得生成的视频人物唇形与输入音频同步。

在这里插入图片描述

Wav2Lip模型解析图

PaddleGAN项目地址:

https://github.com/PaddlePaddle/PaddleGAN

第三个模型:HumanSeg(人像分割),全称为Human Segmentation。这是基于飞桨PaddlePaddle开发的模型,有三种模型可选。因为我们需要高精度分割人像,所以我们就选择了HumanSeg-server,这种高精度模型,适用于服务端GPU且背景复杂的人像场景。

在这里插入图片描述

HumanSeg模型解析图

PaddleSeg项目地址:

https://github.com/PaddlePaddle/PaddleSeg

HumanSeg-server在PaddleHub库的地址:

https://www.paddlepaddle.org.cn/hubdetail?name=humanseg_server&en_category=ImageSegmentation

项目的实现过程

在这里插入图片描述

流程图

通过流程图可以发现,我们的目的是将一张图片变成一张动图,而且越简便越好。我们可以使用Wav2Lip,将图片变成动图,又因为Wav2Lip需要一段音频来进行唇形迁移,所以我选用了FastSpeech来提供这段音频,只需要一段文字就OK了,提高实用性和易操作性。

因为FastSpeech是Parakeet的一个模型,用户需安装Parakeet后使用该模型。不过,安装Parakeet前,先要安装libsndfile1。需要注意的是,AI Studio已经自带libsndfile1了,所以在AI Studio上运行时,用户直接安装Parakeet就OK了!另外,release/v0.1中才有FastSpeech,release/v0.2中则没有FastSpeech。主要参数解析如下:

--use_gpu

选择是否选择GPU进行运行

--output

输出地址

--text_input

文本的地址

%run synthesis.py \
    --use_gpu=1 \
    --alpha=1.0 \
    --checkpoint='./fastspeech_ljspeech_ckpt_1.0/step-162000' \
    --config='./fastspeech_ljspeech_ckpt_1.0/ljspeech.yaml' \
    --output='./synthesis' \
    --vocoder='waveflow' \
    --config_vocoder='./waveflow_res128_ljspeech_ckpt_1.0/waveflow_ljspeech.yaml' \
    --checkpoint_vocoder='./waveflow_res128_ljspeech_ckpt_1.0/step-2000000' \
    --text_input='/home/aistudio/article.txt'

我在写这段代码的时候,非常轻松,因为Parakeet的GitHub上已经附有详细的说明,只需要微调一下即可。

为了提高项目的实用性,我将Parakeet进行改写,把原有只能合成一段话,改为可以将一个文本文档内所有文字转为音频。

--text_input='/home/aistudio/article.txt'

更改前的代码[synthesis.py]:

text = np.asarray(text_to_sequence(text_input))
text = np.expand_dims(text, axis=0)
pos_text = np.arange(1, text.shape[1] + 1)
pos_text = np.expand_dims(pos_text, axis=0)

更改后的代码[synthesis.py]:

for i,line in enumerate(open(args.text_input)): 
        text_input = line
        text = np.asarray(text_to_sequence(text_input))
        text = np.expand_dims(text, axis=0)
        pos_text = np.arange(1, text.shape[1] + 1)
        pos_text = np.expand_dims(pos_text, axis=0)

因为文本文档不单有一行文字,所以我们需要将每一行文字分开合成音频,而后用FFMpeg将所有音频合成一段音频。这样的方式提高了对文本的操作性,也方便后续使用。通过“!ffmpeg -f concat -i waveflow_article3.txt -c copy ‘waveflow_article3.wav’”,我们就完成了第一步,生成了一段朗读文本的音频。

在进行第二步时,要对文件进行处理。音频在上文已经生成好了,接下来就是要生成一段视频。这段视频直接用一张图片生成。因篇幅有限,就不具体介绍将图片合成视频的操作了,相关信息可以查看项目combine_image_to_video函数。

注意:Wav2Lip模型支持单张静态图片和动态视频两种输入,用户可以根据需要自行选择。

文件处理结束后,视频和音频都有了,接下来使用Wav2Lip进行迁移就OK了。

使用Wav2Lip的语句解析:

!export PYTHONPATH=$PYTHONPATH:/home/aistudio/PaddleGAN && python /home/aistudio/PaddleGAN/applications/tools/wav2lip.py --face <视频地址> --audio <音频地址> --outfile <输出地址>  

这里我们没有特殊场景,直接使用预训练模型能让我们更快地得出结果,GitHub的介绍文件中有详细的使用说明。

完成第二步后,我们已经得到了一个“嘴巴会动”的视频。为了使成品更加完美,我们要将视频的背景去除掉。因为HumanSeg已经被飞桨团队封装成PaddleHub的一个模型,因此,模型使用起来非常方便。与此同时,在不用训练的情况下,节省了开发成本和开发时间,还可以直接将视频每帧的人物与背景分割,且将每帧画面还原成一个mp4文件。所以,我在本项目中直接选用了PaddleHub上的代码。

human_seg = hub.Module(name='humanseg_server')
cap_video = cv2.VideoCapture('/home/aistudio/work/img2video/video2.mp4')
fps = cap_video.get(cv2.CAP_PROP_FPS)
save_path = '/home/aistudio/work/img2video/video3.mp4'
width = int(cap_video.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap_video.get(cv2.CAP_PROP_FRAME_HEIGHT))
cap_out = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), fps, (width, height))
prev_gray = None
prev_cfd = None

while cap_video.isOpened():
    ret, frame_org = cap_video.read()
    if ret:
        [img_matting, prev_gray, prev_cfd] = human_seg.video_stream_segment(frame_org=frame_org, frame_id=cap_video.get(1), prev_gray=prev_gray, prev_cfd=prev_cfd)
        img_matting = np.repeat(img_matting[:, :, np.newaxis], 3, axis=2)
        bg_im = np.ones_like(img_matting) * 255
        comb = (img_matting * frame_org + (1 - img_matting) * bg_im).astype(np.uint8)
        cap_out.write(comb)
    else:
        break

cap_video.release()
cap_out.release()

经过三个模型的处理,我们与最终的成品只剩一步之遥。在最后一步中,我们需要将视频(.mp4)文件转为动图(.gif)文件。

import moviepy.editor as mpy
content = mpy.VideoFileClip("/home/aistudio/work/img2video/video3.mp4")
content.write_gif("/home/aistudio/work/img2video/final.gif")

最终,我们得到了一张动图,可以在相关社交媒体中直接作为表情使用。

除了生成表情,飞桨还能做啥?

用户可以通过PaddleSeg-Fast-SCNN(快速语义分割网络)进行实时分割环境

用户也可以用PaddleGAN修复旧视频
项目地址:
https://aistudio.baidu.com/aistudio/projectdetail/1499994

飞桨还有许多有趣的功能,小伙伴们可以自行探索~

总结

此项目融合了多种模型——Fastspeech、Wav2Lip、HumanSeg,分别展示了飞桨框架中音频、生成对抗网络、图像分割的强大实力,也解决了宅友们想自制表情的烦恼。飞桨的预训练模型,降低了AI学习的门槛,让初学者更好地感受到飞桨的魅力,也让AI不断地造福我们的生活。

在这个项目中,我采用def函数的方式,将模型进行封装,提高代码的模块性,也让像我一样初出茅庐的小伙伴更好地读懂代码。

如在使用过程中有问题,可加入官方QQ群进行交流:778260830。

如果您想详细了解更多飞桨的相关内容,请参阅以下文档。

·飞桨官网地址·
https://www.paddlepaddle.org.cn/

·飞桨开源框架项目地址·
GitHub: https://github.com/PaddlePaddle/Paddle
Gitee: https://gitee.com/paddlepaddle/Paddle

图片
👆长按上方二维码立即star!👆

飞桨(PaddlePaddle)以百度多年的深度学习技术研究和业务应用为基础,是中国首个开源开放、技术领先、功能完备的产业级深度学习平台,包括飞桨开源平台和飞桨企业版。飞桨开源平台包含核心框架、基础模型库、端到端开发套件与工具组件,持续开源核心能力,为产业、学术、科研创新提供基础底座。飞桨企业版基于飞桨开源平台,针对企业级需求增强了相应特性,包含零门槛AI开发平台EasyDL和全功能AI开发平台BML。EasyDL主要面向中小企业,提供零门槛、预置丰富网络和模型、便捷高效的开发平台;BML是为大型企业提供的功能全面、可灵活定制和被深度集成的开发平台。

END

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以回答这个问题。以下是一个使用飞桨实现手写数字识别的 Python 程序: ```python import paddle import paddle.fluid as fluid import numpy as np # 定义网络结构 def convolutional_neural_network(img): # 第一层卷积层 conv1 = fluid.layers.conv2d(input=img, num_filters=32, filter_size=5, stride=1, padding=2, act='relu') # 第一层池化层 pool1 = fluid.layers.pool2d(input=conv1, pool_size=2, pool_type='max', pool_stride=2) # 第二层卷积层 conv2 = fluid.layers.conv2d(input=pool1, num_filters=64, filter_size=5, stride=1, padding=2, act='relu') # 第二层池化层 pool2 = fluid.layers.pool2d(input=conv2, pool_size=2, pool_type='max', pool_stride=2) # 第三层卷积层 conv3 = fluid.layers.conv2d(input=pool2, num_filters=64, filter_size=5, stride=1, padding=2, act='relu') # 第三层池化层 pool3 = fluid.layers.pool2d(input=conv3, pool_size=2, pool_type='max', pool_stride=2) # 全连接层 fc = fluid.layers.fc(input=pool3, size=512, act='relu') # 输出层 out = fluid.layers.fc(input=fc, size=10, act='softmax') return out # 定义输入数据 image = fluid.layers.data(name='image', shape=[1, 28, 28], dtype='float32') label = fluid.layers.data(name='label', shape=[1], dtype='int64') # 获取网络输出结果 predict = convolutional_neural_network(image) # 定义损失函数和优化器 cost = fluid.layers.cross_entropy(input=predict, label=label) avg_cost = fluid.layers.mean(cost) optimizer = fluid.optimizer.AdamOptimizer(learning_rate=.001) opts = optimizer.minimize(avg_cost) # 定义训练程序 place = fluid.CPUPlace() exe = fluid.Executor(place) exe.run(fluid.default_startup_program()) # 定义数据读取器 train_reader = paddle.batch(paddle.reader.shuffle(paddle.dataset.mnist.train(), buf_size=500), batch_size=128) test_reader = paddle.batch(paddle.dataset.mnist.test(), batch_size=128) # 开始训练 for pass_id in range(10): # 训练 for batch_id, data in enumerate(train_reader()): train_cost, train_acc = exe.run(program=fluid.default_main_program(), feed={'image': np.array([x[] for x in data]).astype('float32'), 'label': np.array([x[1] for x in data]).astype('int64')}, fetch_list=[avg_cost, predict]) if batch_id % 100 == : print("Pass %d, Batch %d, Cost %f, Acc %f" % (pass_id, batch_id, train_cost[], train_acc[])) # 测试 test_accs = [] test_costs = [] for batch_id, data in enumerate(test_reader()): test_cost, test_acc = exe.run(program=fluid.default_main_program(), feed={'image': np.array([x[] for x in data]).astype('float32'), 'label': np.array([x[1] for x in data]).astype('int64')}, fetch_list=[avg_cost, predict]) test_accs.append(test_acc[]) test_costs.append(test_cost[]) test_cost = (sum(test_costs) / len(test_costs)) test_acc = (sum(test_accs) / len(test_accs)) print("Test: Cost %f, Acc %f" % (test_cost, test_acc)) ``` 这个程序使用了飞桨框架,实现了一个卷积神经网络,用于手写数字识别。训练数据使用了 MNIST 数据集,训练过程中会输出训练和测试的损失和准确率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值