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 相关文章推荐
浅谈django中的认证与登录
Oct 31 Python
Python制作钉钉加密/解密工具
Dec 07 Python
详解python多线程、锁、event事件机制的简单使用
Apr 27 Python
Python读取指定日期邮件的实例
Feb 01 Python
使用python的pandas为你的股票绘制趋势图
Jun 26 Python
详解python列表(list)的使用技巧及高级操作
Aug 15 Python
python实现KNN分类算法
Oct 16 Python
python有序查找算法 二分法实例解析
Feb 18 Python
python实现滑雪者小游戏
Feb 22 Python
python使用梯度下降和牛顿法寻找Rosenbrock函数最小值实例
Apr 02 Python
Pycharm 使用 Pipenv 新建的虚拟环境(图文详解)
Apr 16 Python
pandas数据处理之绘图的实现
Jun 15 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
从C/C++迁移到PHP——判断字符类型的函数
2006/10/09 PHP
Zend studio for eclipse中使php可以调用mysql相关函数的设置方法
2008/10/13 PHP
js replace正则表达式应用案例讲解
2013/01/17 Javascript
JS+flash实现chrome和ie浏览器下同时可以复制粘贴
2013/09/22 Javascript
jquery获取颜色在ie和ff下的区别示例介绍
2014/03/28 Javascript
上传图片js判断图片尺寸和格式兼容IE
2014/09/01 Javascript
NodeJS制作爬虫全过程(续)
2014/12/22 NodeJs
javascript中日期函数new Date()的浏览器兼容性问题
2015/09/05 Javascript
jQuery表格行上移下移和置顶的实现方法
2015/10/08 Javascript
JavaScript学习笔记之数组去重
2016/03/23 Javascript
jQuery实现的简单分页示例
2016/06/01 Javascript
AngularJS实现单独作用域内的数据操作
2016/09/05 Javascript
JavaScript制作颜色反转小游戏
2016/09/25 Javascript
JS实现侧边栏鼠标经过弹出框+缓冲效果
2017/03/29 Javascript
JS简单验证上传文件类型的方法
2017/04/17 Javascript
Vuex和前端缓存的整合策略详解
2017/05/09 Javascript
js的函数的按值传递参数(实例讲解)
2017/11/16 Javascript
Bootstrap fileinput 上传新文件移除时触发服务器同步删除的配置
2018/10/08 Javascript
Vue入门之数量加减运算操作示例
2018/12/11 Javascript
小程序自定义日历效果
2018/12/29 Javascript
es5 类与es6中class的区别小结
2020/11/09 Javascript
python实现在目录中查找指定文件的方法
2014/11/11 Python
Python教程之全局变量用法
2016/06/27 Python
使用pytorch和torchtext进行文本分类的实例
2020/01/08 Python
Tensorflow累加的实现案例
2020/02/05 Python
python实现快递价格查询系统
2020/03/03 Python
解决django xadmin主题不显示和只显示bootstrap2的问题
2020/03/30 Python
如何打包Python Web项目实现免安装一键启动的方法
2020/05/21 Python
CSS3绘制不规则图形的一些方法示例
2015/11/07 HTML / CSS
数据库设计的包括哪两种,请分别进行说明
2016/07/15 面试题
领班岗位职责范文
2014/02/06 职场文书
市场策划求职信
2014/08/07 职场文书
2014年中职班主任工作总结
2014/12/16 职场文书
辣妈辣妹观后感
2015/06/10 职场文书
vue项目中的支付功能实现(微信支付和支付宝支付)
2022/02/18 Vue.js
Spring Bean是如何初始化的详解
2022/03/22 Java/Android