文 | ssw
来源:Python 技术
上回我们活捉一只叫“轩逸”的动力蜘蛛,因为它动力拉垮,实在太慢了
这次让它变身给大家跳个舞,看下边的舞蹈,最拉跨的“动力”,这两个字给力吧!
词云来自轩逸车友圈的真实数据,爬取过程可以参考用python来吐槽,真是太会玩啦
gif不够清晰流畅,所以我们来看看更清晰的视频吧:
前言
利用you-get下载一个B站上跳舞的小姐姐视频,利用懂车帝爬取的“轩逸最不满意”来制作一个漂亮小姐姐词云跳舞视频,一起来看看吧。
1.下载视频
安装 you-get 库
pip install you-get -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
利用 you-get 下载 B 站视频到本地
you-get https://www.bilibili.com/video/BV1rD4y1Q7jc?from=search&seid=10634574434789745619
2.词云文本
脚本要用到的2个文件:
轩逸最不满意.txt
stopwords.txt
已上传 http://ssw.fit/file/
3.从视频中提取图片
import cv2
# ============================ 视频处理 分割成一帧帧图片 =======================================
cap = cv2.VideoCapture(r"不要心动??我要开始表白了【欣小萌】 (P1. 横屏版).mp4")
num = 1
while True:
# 逐帧读取视频 按顺序保存到本地文件夹
ret, frame = cap.read()
if ret:
if 88 <= num < 888:
cv2.imwrite(f"./pictures/img_{num}.jpg", frame) # 保存一帧帧的图片
print(f'========== 已成功保存第{num}张图片 ==========')
num += 1
else:
break
cap.release() # 释放资源
结果如下:
4.利用百度AI进行人像分割
准备工作
百度智能云网址
https://console.bce.baidu.com/
Python SDK参考文档
安装人体分析 Python SDK
pip install baidu-aip
1.领取免费资源
登录进去后,搜索“人体分析”
进入“人体分析”的页面后,领取免费资源
没领取的话,后面脚本的“人像分割”部分会报错,因为使用百度api需要用到这些资源。默认1万次,我已经用了1000多次
2.创建应用
创建一个人像分割的应用,记住你的AppID、API Key、Secret Key,后面会用到。
查看人像分割的 Python SDK 文档,熟悉它的基本使用。
# -*- coding: UTF-8 -*-
import cv2
import base64
import numpy as np
import os
from aip import AipBodyAnalysis
import time
import random
# 利用百度AI的人像分割服务 转化为二值图 有小姐姐身影的蒙版
# 百度云中已创建应用的 APP_ID API_KEY SECRET_KEY
APP_ID = '……'
API_KEY = '……'
SECRET_KEY = '……'
client = AipBodyAnalysis(APP_ID, API_KEY, SECRET_KEY)
# 保存图像分割后的路径
path = './mask_img/'
# os.listdir 列出保存到图片名称
img_files = os.listdir('./pictures')
print(img_files)
for num in range(88, len(img_files) + 1):
# 按顺序构造出图片路径
img = f'./pictures/img_{num}.jpg'
img1 = cv2.imread(img)
height, width, _ = img1.shape
# print(height, width)
# 二进制方式读取图片
with open(img, 'rb') as fp:
img_info = fp.read()
# 设置只返回前景 也就是分割出来的人像
seg_res = client.bodySeg(img_info)
print(111,seg_res)
labelmap = base64.b64decode(seg_res['labelmap'])
nparr = np.frombuffer(labelmap, np.uint8)
labelimg = cv2.imdecode(nparr, 1)
labelimg = cv2.resize(labelimg, (width, height), interpolation=cv2.INTER_NEAREST)
new_img = np.where(labelimg == 1, 255, labelimg)
mask_name = path + 'mask_{}.png'.format(num)
# 保存分割出来的人像
cv2.imwrite(mask_name, new_img)
print(f'======== 第{num}张图像分割完成 ========')
time.sleep(random.randint(1,2))
结果如下:
5.小姐姐跳舞词云生成
# -*- coding: UTF-8 -*-
from wordcloud import WordCloud
import collections
import jieba
import re
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
# 读取数据
with open('轩逸最不满意.txt',encoding='utf8') as f:
data = f.read()
# 文本预处理 去除一些无用的字符 只提取出中文出来
new_data = re.findall('[\u4e00-\u9fa5]+', data, re.S)
new_data = "/".join(new_data)
# 文本分词
seg_list_exact = jieba.cut(new_data, cut_all=True)
result_list = []
with open('stopwords.txt', encoding='utf-8') as f:
con = f.read().split('\n')
stop_words = set()
for i in con:
stop_words.add(i)
for word in seg_list_exact:
# 设置停用词并去除单个词
if word not in stop_words and len(word) > 1:
result_list.append(word)
# 筛选后统计词频
word_counts = collections.Counter(result_list)
path = './wordcloud/'
for num in range(88, 888):
img = f'./mask_img/mask_{num}.png'
# 获取蒙版图片
mask_ = 255 - np.array(Image.open(img))
# 绘制词云
plt.figure(figsize=(8, 5), dpi=200)
my_cloud = WordCloud(
background_color='black', # 设置背景颜色 默认是black
mask=mask_, # 自定义蒙版
mode='RGBA',
max_words=500,
font_path='C:/Windows/Fonts/simhei.TTF', # 设置字体 显示中文
).generate_from_frequencies(word_counts)
# 显示生成的词云图片
plt.imshow(my_cloud)
# 显示设置词云图中无坐标轴
plt.axis('off')
word_cloud_name = path + 'wordcloud_{}.png'.format(num)
my_cloud.to_file(word_cloud_name) # 保存词云图片
plt.close()
print(f'======== 第{num}张词云图生成 ========')
结果如下:
6.合成跳舞视频# -*- coding: UTF-8 -*-
import cv2
import os
# 输出视频的保存路径
video_dir = '轩逸最不满意.mp4'
# 帧率
fps = 30
# 图片尺寸
img_size = (1920, 1080)
fourcc = cv2.VideoWriter_fourcc('M', 'P', '4', 'V') # opencv3.0 mp4会有警告但可以播放
videoWriter = cv2.VideoWriter(video_dir, fourcc, fps, img_size)
img_files = os.listdir('./wordcloud')
for i in range(88, 801):
img_path = './wordcloud/' + 'wordcloud_{}.png'.format(i)
frame = cv2.imread(img_path)
frame = cv2.resize(frame, img_size) # 生成视频 图片尺寸和设定尺寸相同
videoWriter.write(frame) # 写进视频里
print(f'======== 按照视频顺序第{i}张图片合进视频 ========')
videoWriter.release() # 释放资源