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实现Linux的find命令实例分享
Jun 04 Python
浅谈Python实现Apriori算法介绍
Dec 20 Python
django 将model转换为字典的方法示例
Oct 16 Python
Python3.4学习笔记之 idle 清屏扩展插件用法分析
Mar 01 Python
python图形界面开发之wxPython树控件使用方法详解
Feb 24 Python
python和pywin32实现窗口查找、遍历和点击的示例代码
Apr 01 Python
python3.8.1+selenium实现登录滑块验证功能
May 22 Python
Python基础之数据结构详解
Apr 28 Python
pytorch 中nn.Dropout的使用说明
May 20 Python
Python下opencv库的安装过程及问题汇总
Jun 11 Python
详解Golang如何实现支持随机删除元素的堆
Sep 23 Python
Python爬取奶茶店数据分析哪家最好喝以及性价比
Sep 23 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
解析百度搜索结果link?url=参数分析 (全)
2012/10/09 PHP
学习php中的正则表达式
2014/08/17 PHP
浅谈PHP命令执行php文件需要注意的问题
2016/12/16 PHP
PHP实现随机生成水印图片功能
2017/03/22 PHP
PHP ADODB实现分页功能简单示例
2018/05/25 PHP
JavaScript ( (__ = !$ + $)[+$] + ({} + $)[_/_] +({} + $)[_/_] )
2011/02/25 Javascript
js字符串的各种格式的转换 ToString,Format
2011/08/08 Javascript
Jquery实现简单的动画效果代码
2012/03/18 Javascript
laytpl 精致巧妙的JavaScript模板引擎
2014/08/29 Javascript
第三章之Bootstrap 表格与按钮功能
2016/04/25 Javascript
jQuery处理XML文件的几种方法
2016/06/14 Javascript
JavaScript数组迭代方法
2017/03/03 Javascript
VueJs单页应用实现微信网页授权及微信分享功能示例
2017/07/26 Javascript
基于Vue实现页面切换左右滑动效果
2020/06/29 Javascript
JS随机排序数组实现方法分析
2017/10/11 Javascript
详解如何使用 vue-cli 开发多页应用
2017/12/16 Javascript
vue2.0组件之间传值、通信的多种方式(干货)
2018/02/10 Javascript
JavaScript 下载svg图片为png格式
2018/06/21 Javascript
通过jquery的ajax请求本地的json文件方法
2018/08/08 jQuery
vue--点击当前增加class,其他删除class的方法
2018/09/15 Javascript
Vue cli3 库模式搭建组件库并发布到 npm的流程
2018/10/12 Javascript
vue+iview分页组件的封装
2020/11/17 Vue.js
Python2.x和3.x下maketrans与translate函数使用上的不同
2015/04/13 Python
Python使用urllib2模块抓取HTML页面资源的实例分享
2016/05/03 Python
python实现员工管理系统
2018/01/11 Python
Python利用神经网络解决非线性回归问题实例详解
2019/07/19 Python
Python 实现黑客帝国中的字符雨的示例代码
2020/02/20 Python
python中scipy.stats产生随机数实例讲解
2021/02/19 Python
CSS3实现莲花绽放的动画效果
2020/11/06 HTML / CSS
18-35岁旅游团的全球领导者:Contiki
2017/02/08 全球购物
材料物理专业大学毕业生求职信
2013/10/15 职场文书
应届生财务会计求职信
2013/11/05 职场文书
关于运动会的广播稿(10篇)
2014/09/12 职场文书
幼儿园教师求职信
2015/03/20 职场文书
基于Golang 高并发问题的解决方案
2021/05/08 Golang
Mysql数据库手动及定时备份步骤
2021/11/07 MySQL