一、程序背后的小故事:   

因为不想像传统的课设作业一样做一个很多人做过的小游戏,管理程序等,所以花了很长时间在选择一个有趣的程序方向,突然想起来以前看到的字符跳舞视频,突然引起了我的兴趣。分析字符视频的创建流程,想到了利用OpenCV将视频分解成一帧一帧的,然后再对每个图片进行处理。

在处理每帧图片时,可以通过灰度来区分色块,计算每个图片各色块的灰度,将256灰度映射到70个字符上,从而形成字符图片,再利用OpenCV将逐帧字符图片合成成字符视频。这样合成的视频是没有声音的,再利用ffmpeg工具将原视频中的音频分离出来,再与字符视频合成。

本以为大功告成了,突然想到找测试视频时候的窘况,各大网站都不支持直接下载视频。决定再加一个输入视频真实网站直接下载视频的功能,方便视频转换成字符视频。利用youtube-dl模块的功能,完成了输入视频真实网址,再选择视频和音频组合下载不同质量的视频。经过测试,可以下载Bilibili,Youtube等视频网站的视频。

二、程序流程图:

设计这种程序先大致想一下流程,如果不是要交报告想来我也是不会画流程图的,呜呜呜。随手一画,别太较真。

三、代码部分:

1、通过灰度来区分色块,计算每个图片各色块的灰度,将256灰度映射到70个字符,将逐帧图片转换成字符图片(处理逐帧图片核心代码)这个其实是copy了网上其他大佬处理字符图片的办法,嘿嘿嘿

def get_char(r, g, b, alpha=256):  # alpha透明度if alpha == 0:return ' 'length = len(ascii_char)gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)  # 计算灰度unit = (256.0 + 1) / lengthreturn ascii_char[int(gray / unit)]  # 不同的灰度对应着不同的字符# 通过灰度来区分色块
# 该部分以下和灰度值字符画区别所在
def PictureToChar(folder_path, ascii_path, c):print("开始将图片转为字符型:")# 循环读取逐帧图片for icount in range(1, c):IMG = folder_path + str(icount) + '.jpg'  # 文件路径if os.path.exists(IMG):im = Image.open(IMG)# 视频分割后图片的长与宽,与合成视频时要相统一,保存下来,合成字符视频时用到asciiImage = imWIDTH = int(im.width / 6)  # 高度比例为原图的1/6较好,由于字体宽度HEIGHT = int(im.height / 15)  # 高度比例为原图的1/15较好,由于字体高度im_txt = Image.new("RGB", (im.width, im.height), (255, 255, 255))im = im.resize((WIDTH, HEIGHT), Image.NEAREST)txt = ""colors = []for i in range(HEIGHT):for j in range(WIDTH):pixel = im.getpixel((j, i))colors.append((pixel[0], pixel[1], pixel[2]))  # 记录像素颜色信息if (len(pixel) == 4):txt += get_char(pixel[0], pixel[1], pixel[2], pixel[3])else:txt += get_char(pixel[0], pixel[1], pixel[2])txt += '\n'colors.append((255, 255, 255))dr = ImageDraw.Draw(im_txt)font = ImageFont.load_default().font  # 获取字体x = y = 0# 获取字体的宽高font_w, font_h = font.getsize(txt[1])font_h *= 1.37  # 调整后更佳# ImageDraw为每个ascii码进行上色for i in range(len(txt)):if (txt[i] == '\n'):x += font_hy = -font_wdr.text([y, x], txt[i], colors[i])y += font_w# 输出name = str(icount) + '.jpg'print(name)im_txt.save(ascii_path + str(icount) + '.jpg')return asciiImage

2、原视频分割为逐帧图片

def VideoToPicture(path):# 进行视频的载入vc = cv2.VideoCapture(path)print("开始将原视频分割为图片:")c = 0# 判断载入的视频是否可以打开ret = vc.isOpened()# 循环读取视频帧while ret:c = c + 1# 进行单张图片的读取,ret的值为True或者Flase,frame表示读入的图片ret, frame = vc.read()if ret:# 存储为图像cv2.imwrite(folder_path + str(c) + '.jpg', frame)# 输出图像名称print(folder_path + str(c) + '.jpg')# 在一个给定的时间内(单位ms)等待用户按键触发,1mscv2.waitKey(1)else:break# 视频释放vc.release()return c

3、将字符图片合成字符视频,当然,这个时候是没声音的,还需要后续合成。

def charToVideo(ascii_path, asciiImage, path, c, finalVideo_path):# 不同视频编码对应不同视频格式if path.endswith(".mp4"):fourcc = cv2.VideoWriter_fourcc('D', 'I', 'V', 'X')  # 这里是mp4格式,文件名后缀为.mp4elif path.endswith(".avi"):fourcc = cv2.VideoWriter_fourcc('I', '4', '2', '0')  # (例:'I','4','2','0' 对应avi格式)elif path.endswith(".flv"):fourcc = cv2.VideoWriter_fourcc('F', 'L', 'V', '1')  # 该参数是Flash视频,文件名后缀为.flvprint("开始将字符型图片变为视频:")# 输出视频参数设置,包含视频文件名、编码器、帧率、视频宽高(此处参数需和字符图片大小一致)video_file = finalVideo_path + 'out' + '_' + 'ascci' + '_' + pathvideoWriter = cv2.VideoWriter(video_file, fourcc, 30.0,(asciiImage.width, asciiImage.height))# 循环读取图片for i in range(1, c):filename = ascii_path + str(i) + '.jpg'# 判断图片是否存在if os.path.exists(filename):img = cv2.imread(filename=filename)# 在一个给定的时间内(单位ms)等待用户按键触发,100mscv2.waitKey(100)# 将图片写入视频中videoWriter.write(img)print(str(i) + '.jpg' + ' done!')# 视频释放videoWriter.release()print("字符视频已成功生成!!!")return video_file

4、分离原视频中的音乐和字符视频合并,形成有声音的字符视频

def VideoToMp3(path, finalVideo_path):  # 分离原视频中的音乐outMusic_name = finalVideo_path + path.split('.')[0] + '.mp3'  # 将原视频文件后缀名去掉加上.mp3os.system(f"ffmpeg -i {path} -vn {outMusic_name} ")return outMusic_namedef VideoAddMp3(video_file, outMusic_name):  # 将分离出来的原视频中的音乐和字符视频合并video_final = finalVideo_path + 'Final' + '_' + '_' + pathos.system(f"ffmpeg -i {outMusic_name} -i {video_file} {video_final}")

5、视频下载功能(利用youtube-dl下载视频,如果下载有问题可能是重命名的问题,去掉让他直接用解析的网站的名字命名就好了)

def linkToVideo(link_url):#将链接中的视频下载os.system(f"youtube-dl -F {link_url}")print("====请按’视频序号+音频序号‘顺序选择输入视频和音频组合,如果只有一个就只输入一个数字===== ")num = input()VideoDownload_name = input("请给下载视频重命名:  ")os.system(f"youtube-dl -f {num} {link_url} -o {VideoDownload_name}")

以上是部分重要函数部分代码,整个项目已上传Github仓库:Github仓库https://github.com/Dddwaiting/Python

Python 小型课设作业,仅200行代码,使用youtube-dl下载视频,使用OpenCV和ffmpeg处理视频成字符视频相关推荐

  1. python hsv inrange 范围_仅20行代码,用python给证件照换底色

    1.图片来源 该图片来源于百度图片,如果侵权,请联系我删除!图片仅用于知识交流.本文只是为了告诉大家:python其实有很多黑科技(牛逼的库),我们既可以用python处理工作中的一些事儿,同时我们也 ...

  2. 基于 Python 的开源Web开发框架django/哈工大学生成绩管理系统html实现/python结课大作业

    python结课大作业 (一)django安装 (1)django是什么 (2)基于django的网站 (3)django的设计理念 (4)django安装 (二)数据库安装 (1)数据库(DataB ...

  3. 爬虫python代码-Python爬虫教程:200行代码实现一个滑动验证码

    Python爬虫教程:教你用200行代码实现一个滑动验证码 做网络爬虫的同学肯定见过各种各样的验证码,比较高级的有滑动.点选等样式,看起来好像挺复杂的,但实际上它们的核心原理还是还是很清晰的,本文章大 ...

  4. python语言用什么来表明每行代码的层次关系_2021年尔雅通识课《切削原理与刀具》课后习题答案...

    2021年尔雅通识课<切削原理与刀具>课后习题答案 二战后南海局势比较稳定的原因不包括() 答:冷战后相当长时间内,中美战略关系极不稳定 日本是一个多地震国家,主要因为它位于海岛上. 答: ...

  5. python爬虫代码-Python爬虫教程:200行代码实现一个滑动验证码

    Python爬虫教程:教你用200行代码实现一个滑动验证码 做网络爬虫的同学肯定见过各种各样的验证码,比较高级的有滑动.点选等样式,看起来好像挺复杂的,但实际上它们的核心原理还是还是很清晰的,本文章大 ...

  6. python随机生成大写字母_python随机生成大小写字母数字混合密码(仅20行代码)

    用简单的方法生成随机性较大的密码 仅用20行代码随机生成密码 核心思路:利用random模块 random模块随机生成数字,大小写字母,循环次数 while循环+随机生成的循环次数-->随机pl ...

  7. 宁愿“大小周”、每天只写 200 行代码、月薪 8k-17k 人群再涨!揭晓中国开发者真实现状...

    作者 | 郑丽媛 出品 | CSDN(ID:CSDNnews) 程序员,一个圈外人羡慕.圈内人喊苦的"神奇"职业--高薪.福利好是旁人羡慕的理由,高压.加班多却也是他们最常见的写照 ...

  8. 宁愿“大小周”、每天只写 200 行代码、月薪 8k-17k 人群再涨 | 揭晓中国开发者真实现状

    作者 | 郑丽媛 出品 | CSDN(ID:CSDNnews) 程序员,一个圈外人羡慕.圈内人喊苦的"神奇"职业--高薪.福利好是旁人羡慕的理由,高压.加班多却也是他们最常见的写照 ...

  9. 200行代码如何实现人脸识别开锁应用?

    多种条件限制之下,如何完成真人实景游戏场景下的人脸识别开锁功能?云加社区邀请到腾讯科技产品经理-高树磊,分享他是如何用200行代码,从系统架构.硬件选型.到系统搭建,一步步地实现此精致小巧的人脸识别开 ...

最新文章

  1. 桌面虚拟化之远程协助
  2. SQL查询库、表,列等的一些操作
  3. 递归方法计划销售订单的计划物料成本
  4. 循环节长度 java,第六届蓝桥杯java试题-循环节长度
  5. HttpDNS功能说明及实现
  6. lepus mysql 慢查询_天兔 -Lepus 慢查询分析平台配置
  7. struct结构体初始化3种方法
  8. 前端学习(749):函数两种声明方式
  9. -bash: mysql: command not found解决方法(zabbix监控mysql失败)
  10. Entity Framework 6新特性:全局性地自定义Code First约定
  11. 华为olt ma5680t常用命令详解
  12. GJB 软件定型测评报告(模板)
  13. 免费WEB打印控件(插件)——打天下
  14. 测度论与概率论笔记1:可测空间与可测函数
  15. DTD语法 (元素、属性、实体声明)
  16. Flutter Sliver大家庭之Sliver实战④
  17. import torchvision报错,UserWarning: Failed to load image Python extension: Could not find module ‘C:\U
  18. 李宏毅学习笔记43.More about Domain Adaptation. Part II. Applications
  19. UUID 通用唯一识别码(Universally Unique Identifier)介绍
  20. 我的高德地图之定位,Marker,位置信息。

热门文章

  1. 怎样翻译word文档中的英文,仅需三分钟即可搞定
  2. 基于SSM框架的健身房会员系统
  3. docker galaxy_前Galaxy Note 7车主可以在Note 8上获得大量优惠
  4. 中国网络音频产品行业市场供需与战略研究报告
  5. 注塑模具设计的总体原则和要求
  6. 计算机上的计算器符号功能详解
  7. 局域网控制计算机运行程序,局域网控制远程计算机教程的方法
  8. 女孩子适合学计算机专业么,女生学计算机专业好吗 有哪些优势
  9. 一种通过刷写替换boot的方法
  10. 〖Web全栈开发①〗—网络编程基础(上)