Python实现视频转字符视频(video2str)

思路

本文实现思路分为如下三步:

  • 将视频转化为一帧一帧的图片(video2image)
  • 把图片转化为字符图片(image2str)
  • 把一帧一帧的字符图片组合成字符视频(image2video

References

Pillow文档
python将图片转化为字符图
OpenCV-视频转图片/图片转视频
Python+opencv将图片生成成视频

代码

import cv2
import numpy as np
from PIL import Image,ImageFont,ImageDraw
# =============================================================================
# video2image
# =============================================================================
#import cv2
def getFrame(videoPath, savePicturePath):
    cap = cv2.VideoCapture(videoPath)
    numFrame = 0
    rval=cap.isOpened()
    while rval:
        numFrame+=1
        rval,frame=cap.read()
        if rval:
    	    #jinji为py文件的当前目录下新建的文件夹
            cv2.imwrite('./jinji/'+str(numFrame) + '.jpg', frame) #文件保存路径不能有中文
            #cv2.imwrite(savePicturePath+str(numFrame) + '.jpg', frame) 如果你的svPath不含有中文,可以这样使用
            cv2.waitKey(1)
        else:
            break
    return numFrame

videoPath=r'D:\学习\计算机视觉\进击的巨人\勇士.mp4'
savePicturePath=r'D:\学习\计算机视觉\进击的巨人'
numFrame=getFrame(videoPath,savePicturePath)#numFrame表示有多少张图片,下面有用到

# =============================================================================
# image2str
# =============================================================================
#import numpy as np
#from PIL import Image,ImageFont,ImageDraw

def img_to_char(image_path,height):
     #读取图片
    img = Image.open(image_path)
    img_width, img_height = img.size
    # 假设字符的宽度是高度的2倍
    width = 2* height * img_width // img_height
    img = img.resize((width, height), Image.ANTIALIAS)#图片的缩放
    #读取图片的灰度值矩阵
    data = np.array(img.convert('L'))
    #设定字符,字符数要是256的因子,这里取32
    chars = "#RMNHQODBWGPZ*@$C&98?32I1>!:-;. "
    N = len(chars)
    #计算每个字符的区间,//取整
    n = 256 // N 
    #result是字符结果
    result = ''
    for i in range(height):
        for j in range(width):
            result += chars[data[i][j] // n]
        result += '\n'
    
    #保存为txt文件
    with open(image_file+'str.txt', mode='w') as f:
        f.write(result)
    
    #保存字符图片    
    font = ImageFont.truetype(r"控制面板\所有控制面板项\字体\Calibri\calibri.ttf",1)
    im = Image.new("RGB",(width,height*2),(255,255,255))
    dr = ImageDraw.Draw(im)
    x,y=0,0
    lines2=result.split('\n')[:height]
    for line in lines2:
        for word in line:
            dr.text((x,y),word,font=font,fill=0)
            x+=1
        x=0    
        y += 2 #假设一个字符占2*1像素
    im.save(image_file+'img.jpg')
    

numframes=numFrame #numFrame表示有多少图片
image_file_list=[ r'D:\学习\计算机视觉\jinji\{}'.format(i) for i in range(1,numframes+1)]#此处路径是刚刚图片保存的路径
#image_file = r'D:\学习\计算机视觉\jinji\1'
image_file_format='.jpg'
height = 150   #可自己调
task=0
for image_file in image_file_list:    
    image_path=image_file+image_file_format
    img_to_char(image_path,height)
    task+=1
    print("我已经完成{}/{}啦0.0".format(task,numframes))
    
# =============================================================================
# image2video
# =============================================================================
#import cv2
fps = 30.17 #根据自己视频秒数和分割的帧数来算
img_temp = Image.open(image_path)
img_width, img_height = img_temp.size
width = 2* height * img_width // img_height
size = (width,height*2) 
videowriter = cv2.VideoWriter("braves.MP4",cv2.VideoWriter_fourcc(*'MP42'),fps,size)#mp4比avi效果好一些;文件名最好用英文
 
for i in range(1,numframes):
    img = cv2.imread('./img/'+'{}img.jpg'.format(i))
    videowriter.write(img)
    
videowriter.release()

示例gif

这个示例是之前做的“鸡你太美”先看下效果的,发现还可以。(由于大小限制,这边只用了70帧来制作gif)

你可能感兴趣的:(Python,demo)