利用Python做一个舞动起来的小姐姐词云视频

2023-09-25 7 0

文章目录

    • 实现过程
        • 一、选取视频并下载
        • 二、获取视频的弹幕内容
        • 三、从视频中提取图片
        • 四、人像分割(借助免费的百度AI)
        • 五、词云生成
        • 六、查看原视频中的帧率和图片尺寸
        • 七、合成跳舞视频
        • 八、加入原视频音频加以渲染
        • 九、参考博文

实现过程

一、选取视频并下载

可以利用you-get把哔哩哔哩的视频下载到本地
具体可参考上一篇文章:传送门

二、获取视频的弹幕内容

爬取弹幕内容,我在这里给大家推荐一个非常好用的第三方库,bilibili_api,详细内容可参考官方文档:传送门
代码如下:

from bilibili_api import Verify, videoverify = Verify(sessdata="你的sessdata值的内容", csrf="你的csrf值的内容")
# 参数
BVID = "这里填爬取视频弹幕的BV号"
# 获取视频信息
info = video.get_video_info(bvid=BVID, verify=verify)# # 假设这里获取 p1 的最新弹幕信息,需要取出 page_id,即每 p 都有自己的编号
page_id = info["pages"][0]["cid"]# 然后开始获取弹幕
danmakus = video.get_danmaku(bvid=BVID, page_id=page_id)# 保存弹幕内容
list_all = list()
filename = 'D:/danmu.txt'  # 这里是保存的地址
for dm in danmakus:dm = dm.textlist_all.append(dm)# print(list_all)
file = open(filename, 'w', encoding='utf-8')
for i in range(len(list_all)):s = str(list_all[i]).replace('[', '').replace(']', '')  # 去除[]s = s.replace("'", '').replace(',', '') + '\n'  # 去除单引号,逗号,每行末尾追加换行符file.write(s)  # 将列表中数据依次写入文件中
print('弹幕获取完毕!!!')
file.close()

Q:sessdata和csrf的值怎么找?

A:在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里面找到sessdatabili_jct的内容即可(官方文档说,bili_jct的值的值就是csrf的值)

注意:这两个值不要暴露给别人,可能会被盗号(来自官方文档的提示)

结果显示如下:
在这里插入图片描述

三、从视频中提取图片

(一帧一帧地提取,工程量还是蛮大的)
我们可以使用下面的代码先查看,总共可以分为多少张。

import cv2
# 查看总共有多少张图片
cap = cv2.VideoCapture(r"这里是下载的视频所在的路径")
num = 1
while True:ret, frame = cap.read()if ret:num += 1else:breakprint(num)
cap.release()   # 释放资源

emmm,我爬的这个一分多钟的视频有两千多张,我们可以选取一个范围,就取从第521张到第1314张吧。

import cv2
cap = cv2.VideoCapture(r"这里是下载的视频所在的路径")
num = 1
while True:# 逐帧读取视频  按顺序保存到本地文件夹ret, frame = cap.read()if ret:if 521 <= num < 1314:cv2.imwrite(f"这里填预保存图片文件夹的路径/img_{num}.jpg", frame)   # 保存一帧帧的图片print(f'========== 已成功保存第{num}张图片 ==========')num += 1else:break
cap.release()   # 释放资源

结果如下:
在这里插入图片描述

四、人像分割(借助免费的百度AI)

首先,打开百度AI,传送门,点击右上角的控制台,使用手机扫码登录。登录成功,点击左栏的人脸分析,进行应用创建,创建成功之后,你会在你的应用里得到三个值:
在这里插入图片描述
这三个值马上就会用到。
接着,查看人脸分析的Python SDK文件,文件链接传送门
基本熟悉一下它的应用。

最后,直接上代码:

from aip import AipBodyAnalysis
import os
import cv2
import base64
import numpy as np
import time
import random# 百度云中已创建应用的  APP_ID API_KEY SECRET_KEY
APP_ID = '你的APP_ID的值'
API_KEY = '你的API_KEY的值'
SECRET_KEY = '你的SECRET_KEY的值'client = AipBodyAnalysis(APP_ID, API_KEY, SECRET_KEY)
# 保存图像分割后的路径
path = '分割后的图像,想要保存的文件夹的路径'
# os.listdir  列出保存到图片名称
img_files = os.listdir('上一步中,保存提取出来的图片的文件夹路径')
# print(img_files)
for num in range(521, 1314):  # 图片范围# 按顺序构造出图片路径img = f'上一步中,保存提取出来的图片的文件夹路径/img_{num}.jpg'img1 = cv2.imread(img)  # imread读取图片height, width, _ = img1.shape# 二进制方式读取图片with open(img, 'rb') as fp:img_info = fp.read()# 设置只返回前景   也就是分割出来的人像seg_res = client.bodySeg(img_info)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))

结果如下:
在这里插入图片描述

五、词云生成
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('存放弹幕内容的文件路径', "rt", encoding="utf-8") 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 = '保存词云图片的文件夹路径'for num in range(521, ):img = f'保存分割后的图像的文件夹的路径/mask_{num}.png'# 获取蒙版图片mask_ = 255 - np.array(Image.open(img))# 绘制词云plt.figure(figsize=(8, 5), dpi=200)my_cloud = WordCloud(background_color='black',  # 设置背景颜色  默认是blackmask=mask_,      # 自定义蒙版mode='RGBA',max_words=500,font_path='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)    # 保存词云图片print(f'======== 第{num}张词云图生成 ========')

Q:stopwords.txt文件是什么?

A:就是一个固定的文件,下载下来即可。百度网盘传送门
提取码:iits

运行结果如下:
在这里插入图片描述

在这里插入图片描述

六、查看原视频中的帧率和图片尺寸
import cv2
mp4 = cv2.VideoCapture(r"这里是下载的视频所在的路径")  # 读取视频
is_opened = mp4.isOpened()  # 判断是否打开
print(is_opened)
fps = mp4.get(cv2.CAP_PROP_FPS)  # 获取视频的帧率
print(fps)
width = mp4.get(cv2.CAP_PROP_FRAME_WIDTH)  # 获取视频的宽度
height = mp4.get(cv2.CAP_PROP_FRAME_HEIGHT)  # 获取视频的高度
print(str(width) + "x" + str(height))
i = 1
time_f = int(fps)

运行结果如下:
在这里插入图片描述

七、合成跳舞视频
import cv2
import os# 输出视频的保存路径
video_dir = '保存视频的文件路径'
# 帧率(最好填上一步得到的帧率)
fps = 25
# 图片尺寸(最好填上一步得到的尺寸)
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('词云图片所在的文件路径')for i in range(521, 1314):img_path = '词云图片所在的文件路径/' + 'wordcloud_{}.png'.format(i)frame = cv2.imread(img_path)frame = cv2.resize(frame, img_size)   # 生成视频   图片尺寸和设定尺寸相同videoWriter.write(frame)      # 写进视频里print(f'======== 按照视频顺序第{i}张图片合进视频 ========')videoWriter.release()   # 释放资源

运行结果如下:
在这里插入图片描述

八、加入原视频音频加以渲染

emmmm,我几个星期前刚把剪辑软件《达芬奇》删掉,于是我用的哔哩哔哩云剪辑,上传了,想看的小伙伴可以去看一下。

视频传送门

也许只有看到这篇文章并且看到这里的小伙伴才会看到这个视频吧。

九、参考博文

参考博文:传送门

代码编程
赞赏

相关文章

eclipse中更改SVN账号的步骤
eclipse中配置tomcat插件的步骤
eclipse中安装svn插件的步骤
按月统计员工登录情况及日期函数的运用
软件项目版本号设置
TexturePacker 图片打包工具