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处理圆角图片、圆形图片的例子
Apr 25 Python
python中使用enumerate函数遍历元素实例
Jun 16 Python
深入讨论Python函数的参数的默认值所引发的问题的原因
Mar 30 Python
Python2.x中文乱码问题解决方法
Jun 02 Python
python 内置函数filter
Jun 01 Python
Python实现扩展内置类型的方法分析
Oct 16 Python
python用BeautifulSoup库简单爬虫实例分析
Jul 30 Python
Python Django的安装配置教程图文详解
Jul 17 Python
分享一个pycharm专业版安装的永久使用方法
Sep 24 Python
通过 Python 和 OpenCV 实现目标数量监控
Jan 05 Python
如何使用Cython对python代码进行加密
Jul 08 Python
tensorflow学习笔记之tfrecord文件的生成与读取
Mar 31 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
DOMXML函数笔记
2006/10/09 PHP
PHP stristr() 函数(不区分大小写的字符串查找)
2010/06/03 PHP
PHP 字符串正则替换函数preg_replace使用说明
2011/07/15 PHP
laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析
2019/12/20 PHP
在jquery中处理带有命名空间的XML数据
2011/06/13 Javascript
jQuery中bind()方法用法实例
2015/01/19 Javascript
ionic 自定义弹框效果
2017/06/27 Javascript
JS实现div模块的截图并下载功能
2017/10/17 Javascript
Vue全局分页组件的实现代码
2018/08/10 Javascript
利用JS动态生成隔行换色HTML表格的两种方法
2018/10/09 Javascript
Vue实战教程之仿肯德基宅急送App
2019/07/19 Javascript
react-intl实现React国际化多语言的方法
2020/09/27 Javascript
python实现博客文章爬虫示例
2014/02/26 Python
python实现批量下载新浪博客的方法
2015/06/15 Python
详解python的几种标准输出重定向方式
2016/08/15 Python
Python实现备份MySQL数据库的方法示例
2018/01/11 Python
python format 格式化输出方法
2018/07/16 Python
Python实现监控键盘鼠标操作示例【基于pyHook与pythoncom模块】
2018/09/04 Python
Python 中判断列表是否为空的方法
2019/11/24 Python
python实现回旋矩阵方式(旋转矩阵)
2019/12/04 Python
python怎么删除缓存文件
2020/07/19 Python
CSS3 linear-gradient线性渐变生成加号和减号的方法
2017/11/21 HTML / CSS
css3中less实现文字长阴影(long shadow)
2020/04/24 HTML / CSS
英国天然有机美容护肤品:Neal’s Yard Remedies
2018/05/05 全球购物
美国牙科折扣计划:DentalPlans.com
2019/08/26 全球购物
后勤副校长自我鉴定
2013/10/13 职场文书
应届生求职推荐信
2013/10/28 职场文书
办公室秘书自我鉴定
2014/01/18 职场文书
教师简历自我评价
2014/02/03 职场文书
自考毕业自我鉴定
2014/03/18 职场文书
2014年教师业务工作总结
2014/12/19 职场文书
蜗居观后感
2015/06/11 职场文书
职场新人知识:如何制定一份合理的工作计划?
2019/09/11 职场文书
python小程序之飘落的银杏
2021/04/17 Python
详解Python中下划线的5种含义
2021/07/15 Python
修改Nginx配置返回指定content-type的方法
2022/09/23 Servers