这几天报名参加了百度的免费培训 深度学习7日入门-CV疫情特辑,学到了好多东西,本来是有 Python 基础的,但是对算法不熟,磕磕绊绊的也都学了下来,感觉百度的 PaddlePaddle、PaddleHub、AI Studio 都还不错。
百度 AI Studio 深度学习平台是针对AI学习者的在线一体化开发实训平台。平台集合了AI教程, 深度学习样例工程, 各领域的经典数据集, 云端的超强运算及存储资源, 以及比赛平台和社区,从而解决学习者在AI学习过程中的一系列难题, 例如教程水平不一, 教程和样例代码难以衔接, 高质量的数据集不易获得, 以及本地难以使用大体量数据集进行模型训练。
PaddlePaddle安装文档 AI Studio 提供了免费的 CPU、GPU 运行环境,只不过 GPU 经常抢不到,只能自己本地安装,没有显卡的同学,最好还是自己买一个显卡,本地安装 PP 随时方便的进行学习。
重点说一下使用 PaddleHub 的模型进行图像处理。
PaddleHub是飞桨预训练模型管理和迁移学习工具,通过PaddleHub开发者可以使用高质量的预训练模型结合Fine-tune API快速完成迁移学习到应用部署的全流程工作。其提供了飞桨生态下的高质量预训练模型,涵盖了图像分类、目标检测、词法分析、语义模型、情感分析、视频分类、图像生成、图像分割、文本审核、关键点检测等主流模型。
一个简单的例子
比如上图 test_image.jpg,用下面两行代码即可完成对人体部件的识别
$ hub run ace2p --input_path test_image.jpg
$ hub run deeplabv3p_xception65_humanseg --input_path test_image.jpg
下面是识别结果,可以看到头发、脸部、身体、四肢、都很好的识别出来。
视频处理
下面的代码参考自 Github
第一步:把视频所有帧转换成图片
这里使用了 CV2 这个库
def CutVideo2Image(video_path, img_path):
"""从视频中提取每一帧图像
"""
cap = cv2.VideoCapture(video_path)
index = 0
while(True):
ret,frame = cap.read()
if ret:
cv2.imwrite('%s/%d.jpg' % (img_path, index), frame)
index += 1
else:
break
cap.release()
print('Video cut finish, all %d frame' % index)
第二步:抠图
def GetHumanSeg(in_path, out_path):
"""抠图,把图片转换成只有任务的 png 格式
"""
# load model
module = hub.Module(name="deeplabv3p_xception65_humanseg")
# config
frame_path = in_path
test_img_path = [os.path.join(frame_path, fname) for fname in os.listdir(frame_path)]
input_dict = {"image": test_img_path}
results = module.segmentation(data=input_dict, output_dir=out_path, use_gpu=True)
第三步:给图片加上新的背景
def BlenDIMg(fore_image, base_image, output_path):
"""
将抠出的人物图像换背景
fore_image: 前景图片,抠出的人物图片
base_image: 背景图片
"""
# 读入图片
base_image = Image.open(base_image).convert('RGB')
fore_image = Image.open(fore_image).resize(base_image.size)
# 图片加权合成
scope_map = np.array(fore_image)[:,:,-1] / 255
scope_map = scope_map[:,:,np.newaxis]
scope_map = np.repeat(scope_map, repeats=3, axis=2)
res_image = np.multiply(scope_map, np.array(fore_image)[:,:,:3]) + np.multiply((1-scope_map), np.array(base_image))
#保存图片
res_image = Image.fromarray(np.uint8(res_image))
res_image.save(output_path)
第四步:把图片帧合并成视频
cv2.VideoWriter
里面的 30.0 是视频的帧率,要根据原视频改一下,不然生成的视频时长会和原来不一样,下面的合并音频也会出问题。
def CombVideo(in_path, out_path, size):
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(out_path,fourcc, 30.0, size)
files = os.listdir(in_path)
for i in range(len(files)):
img = cv2.imread(in_path + '%d.png' % i)
out.write(img)#保存帧
out.release()
还有一步
上一步合成的视频是没有声音的,接下来用 ffmpeg 抽取原视频的音频,合并到新的视频里
# 提取音频为 audio.mp3
ffmpeg -i video/原视频.flv video/audio.mp3
# 合并第四步的结果 outpu.mp4 和 audio.mp3 最终文件为 final.mp4
ffmpeg -i output.mp4 -i video/audio.mp3 -c copy video/final.mp4
成果展示
图片对比:
原图:
抠图后:
添加绿幕背景: