python将视频转换为全字符视频


Posted in Python onApril 26, 2019

简介

如何简单的使用python来实现将一部视频转换为字符画视频的效果。
其实,大家都知道视频就是一帧一帧的图片构成的。  

python将视频转换为全字符视频

那么如今我们想要实现,将视频转换为字符视频,那么是不是可以认为只要将一部视频全部逐帧拆解成图片,然后采取和以前相同的将图片转换为字符画的算法即可。然后在将这些图片按照原先的视频的格式封装起来就可以了。

既然有了想法,那接下来,自然是开始实际开发了。

代码

以下是相关部分的代码:

#-*- coding:utf-8 -*-
import argparse
import os
import cv2
import subprocess
from cv2 import VideoWriter,VideoWriter_fourcc,imread,resize
from PIL import Image, ImageFont, ImageDraw
#命令行输入参数处理
parser = argparse.ArgumentParser()
parser.add_argument('file')
parser.add_argument('-o','--output')
parser.add_argument('-f','--fps',type = float, default = 24)#帧
parser.add_argument('-s','--save',type = bool, nargs='?', default = False, const = True)
#是否保留Cache文件,默认不保存

#获取参数
args = parser.parse_args()
INPUT = args.file
OUTPUT = args.output
SAVE = args.save
FPS = args.fps
#像素对应ascii码

ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:oa+>!:+. ")
#ascii_char = list("MNHQ$OC67+>!:-. ")
#ascii_char = list("MNHQ$OC67)oa+>!:+. ")

#将像素转换为ascii码
def get_char(r,g,b,alpha = 256):
 if alpha == 0:
  return ''
 length = len(ascii_char)
 gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
 unit = (256.0+1)/length
 return ascii_char[int(gray/unit)]

#将txt转换为图片
def txt2image(file_name):
 im = Image.open(file_name).convert('RGB')
 #gif拆分后的图像,需要转换,否则报错,由于gif分割后保存的是索引颜色
 raw_width = im.width 
 raw_height = im.height
 width = int(raw_width/6)
 height = int(raw_height/15)
 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))

 im_txt = Image.new("RGB",(raw_width,raw_height),(255,255,255))
 dr = ImageDraw.Draw(im_txt)
 #font = ImageFont.truetype(os.path.join("fonts","汉仪楷体简.ttf"),18)
 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_h
   y=-font_w
  dr.text((y,x),txt[i],font = font, fill = colors[i])
  y+=font_w

 name = file_name
 print(name+' changed')
 im_txt.save(name)
#将视频拆分成图片
def video2txt_jpg(file_name):
 vc = cv2.VideoCapture(file_name)
 c=1
 if vc.isOpened():
  r,frame = vc.read()
  if not os.path.exists('Cache'):
   os.mkdir('Cache')
  os.chdir('Cache')
 else:
  r = False
 while r:
  cv2.imwrite(str(c)+'.jpg',frame)
  txt2image(str(c)+'.jpg')#同时转换为ascii图
  r,frame = vc.read()
  c += 1
 os.chdir('..')
 return vc

#将图片合成视频
def jpg2video(outfile_name,fps):
 fourcc = VideoWriter_fourcc(*"MJPG")

 images = os.listdir('Cache')
 im = Image.open('Cache/'+images[0])
 vw = cv2.VideoWriter(outfile_name+'.avi',fourcc,fps,im.size)

 os.chdir('Cache')
 for image in range(len(images)):
  #Image.open(str(image)+'.jpg').convert("RGB").save(str(image)+'.jpg')
  frame = cv2.imread(str(image+1)+'.jpg')
  vw.write(frame)
  print(str(image+1)+'.jpg'+' finished')
 os.chdir('..')
 vw.release()

#递归删除目录
def remove_dir(path):
 if os.path.exists(path):
  if os.path.isdir(path):
   dirs = os.listdir(path)
   for d in dirs:
    if os.path.isdir(path+'/'+d):
     remove_dir(path+'/'+d)
    elif os.path.isfile(path+'/'+d):
     os.remove(path+'/'+d)
   os.rmdir(path)
   return
  elif os.path.isfile(path):
   os.remove(path)
  return
#调用ffmpeg获取mp3音频文件
def video2mp3(file_name):
 outfile_name = file_name.split('.')[0]+'.mp3'
 subprocess.call('ffmpeg -i '+file_name+' -f mp3 '+outfile_name,shell = True)
#合成音频和视频文件
def video_add_mp3(file_name,mp3_file):
 outfile_name = file_name.split('.')[0]+'-txt.mp4'
 subprocess.call('ffmpeg -i '+file_name+' -i '+mp3_file+' -strict -2 -f mp4 '+outfile_name,shell = True)

if __name__=='__main__':
 vc = video2txt_jpg(INPUT)
 FPS = vc.get(cv2.CAP_PROP_FPS)#获取帧率
 vc.release()

 jpg2video(INPUT.split('.')[0],FPS)
 print(INPUT,INPUT.split('.')[0]+'.mp3')
 video2mp3(INPUT)
 video_add_mp3(INPUT.split('.')[0]+'.avi',INPUT.split('.')[0]+'.mp3')

 if(not SAVE):
  remove_dir("Cache")
  os.remove(INPUT.split('.')[0]+'.mp3')
  os.remove(INPUT.split('.')[0]+'.avi')

流程图

这次python编程的流程图如下:

python将视频转换为全字符视频

注意事项

在编程的过程中有需要注意的几点:

  • 这次编程使用到了opencv库,需要安装
  • 帧率的获取可以通过这个函数——FPS = vc.get(cv2.CAP_PROP_FPS)
  • 合成后的视频是没有声音的,我们使用ffmpeg进行合成

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现删除Android工程中的冗余字符串
Jan 19 Python
Python3实现发送QQ邮件功能(文本)
Dec 15 Python
Python利用字典将两个通讯录文本合并为一个文本实例
Jan 16 Python
python生成tensorflow输入输出的图像格式的方法
Feb 12 Python
Python lambda函数基本用法实例分析
Mar 16 Python
Python实现的寻找前5个默尼森数算法示例
Mar 25 Python
使用Scrapy爬取动态数据
Oct 21 Python
Django如何简单快速实现PUT、DELETE方法
Jul 24 Python
在pytorch 中计算精度、回归率、F1 score等指标的实例
Jan 18 Python
win10安装tensorflow-gpu1.8.0详细完整步骤
Jan 20 Python
vscode配置anaconda3的方法步骤
Aug 08 Python
Python如何截图保存的三种方法(小结)
Sep 01 Python
使用Python创建简单的HTTP服务器的方法步骤
Apr 26 #Python
Python3.5内置模块之random模块用法实例分析
Apr 26 #Python
python3.5安装python3-tk详解
Apr 26 #Python
Python3.5基础之变量、数据结构、条件和循环语句、break与continue语句实例详解
Apr 26 #Python
python实现名片管理系统项目
Apr 26 #Python
python面向对象实现名片管理系统文件版
Apr 26 #Python
Python判断对象是否为文件对象(file object)的三种方法示例
Apr 26 #Python
You might like
Terran魔法科技
2020/03/14 星际争霸
javascript 小型动画组件与实现代码
2010/06/02 PHP
php查询mssql出现乱码的解决方法
2014/12/29 PHP
PHP实现自动对图片进行滚动显示的方法
2015/03/12 PHP
PHP+JQUERY操作JSON实例
2017/03/23 PHP
Laravel框架控制器的middleware中间件用法分析
2019/09/30 PHP
地震发生中逃生十大法则
2008/05/12 Javascript
js post方式传递提交的实现代码
2010/05/31 Javascript
jquery ajax实现下拉框三级无刷新联动,且保存保持选中值状态
2013/10/29 Javascript
JavaScript利用正则表达式去除日期中的-
2014/06/09 Javascript
JavaScript中的console.log()函数详细介绍
2014/12/29 Javascript
javascript实现在下拉列表中显示多级树形菜单的方法
2015/08/12 Javascript
jQuery超赞的评分插件(8款)
2015/08/20 Javascript
Bootstrap 过渡效果Transition 模态框(Modal)
2017/03/17 Javascript
vue 自动化路由实现代码
2019/09/03 Javascript
ant design的table组件实现全选功能以及自定义分页
2020/11/17 Javascript
[03:23:49]2016.12.17日完美“圣”典全回顾
2016/12/19 DOTA
python opencv之SURF算法示例
2018/02/24 Python
运行django项目指定IP和端口的方法
2018/05/14 Python
PyCharm设置SSH远程调试的方法
2018/07/17 Python
在Mac上删除自己安装的Python方法
2018/10/29 Python
详解pandas中MultiIndex和对象实际索引不一致问题
2019/07/23 Python
docker django无法访问redis容器的解决方法
2019/08/21 Python
Python利用多线程同步锁实现多窗口订票系统(推荐)
2019/12/22 Python
win10下python2和python3共存问题解决方法
2019/12/23 Python
keras 自定义loss model.add_loss的使用详解
2020/06/22 Python
Python中使用aiohttp模拟服务器出现错误问题及解决方法
2020/10/31 Python
使用phonegap获取设备的一些信息方法
2017/03/31 HTML / CSS
英国最出名高街品牌:Forever Unique
2018/02/24 全球购物
物理系毕业生自荐信
2013/11/01 职场文书
遗体告别仪式答谢词
2014/01/23 职场文书
求职意向书
2014/04/01 职场文书
行政申诉状范文
2015/05/20 职场文书
2015暑期爱心支教策划书
2015/07/14 职场文书
新郎父母婚礼致辞
2015/07/27 职场文书
公司岗位说明书
2015/10/08 职场文书