欢迎光临散文网 会员登陆 & 注册

字符画转视频[Termux,Python]

2023-08-09 10:27 作者:真雷神托儿  | 我要投稿

#正文不能为空

import os,sys
import numpy as np
from tqdm import tqdm
from PIL import Image,ImageDraw,ImageFont
from multiprocessing import Process,Queue,Manager
exec('import CV2 as cv'.lower())
'''
这么写是因为B站专栏有BUG,字符串'cv'加一个数字,
会把其中的cv强制转换为大写的CV  !!!
比如 :
import CV2
'''
########################################
#最终比例
P2 = 10

#图片比例缩放(0.05-0.2),原视频单帧图像尺寸越大,值越小;反之,值越大
P1 = 0.05

#是否二值化
TH = True

#二值化阈值,大于阈值设为白色,其他黑色
THRESH = 125

#处理图片用到的CPU个数
IMG2STR_CPU_COUNT = 4
########################################

img_str = Manager().dict()
cap_list = Queue(100)
END = Queue(1)
FPS = Queue(2)

pix =''' .'`^",:;Il!i><~+_-?][}{1)(|\/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@'''
pixgray2str= lambda p: pix[(255 - p) * 68 //255]

def cap_while(cap_list,mv_path,END,FPS) :
    cap = cv.VideoCapture(mv_path) 
    if not FPS.full() :
        FPS.put(cap.get(cv.CAP_PROP_FPS))
        FPS.put(int(cap.get(cv.CAP_PROP_FRAME_COUNT)))
    b = 0
    while True :
        a = cap.read()
        if a[0] == True:
            cap_list.put((b,a[1]))
            b += 1
        else :
            for _ in range(IMG2STR_CPU_COUNT) :
                cap_list.put(False)
            END.put(b)
            cap.release()
            break 

def img2str(cap_list,img_str) :
    while True :
        if len(img_str) >= 500 :
            continue
        A = cap_list.get()
        if A :
            img = A[1]
            gray_img = cv.cvtColor(img,cv.COLOR_RGB2GRAY)
            if TH :
                _,gray_img = cv.threshold(gray_img,THRESH,255,cv.THRESH_BINARY)
            Y,X = gray_img.shape
            s_img = cv.resize(gray_img,(int(X*P1),int(Y*P1)),interpolation=cv.INTER_AREA)
            y,x = s_img.shape
            txt = ''
            for i in s_img :
                for p in i :
                    txt += pixgray2str(p)*2
                txt += '\n'
            font = ImageFont.load_default()
            bg_color = 'black'
            #bg_color = 'white'
            im_out = Image.new('L',(x*P2,y*P2), bg_color)
            draw = ImageDraw.Draw(im_out)
            draw.text((0,0),txt,fill=(255),font=font)
            img_new_str = np.asarray(im_out)
            img_str[A[0]] = img_new_str
        else :
            break
        
def videowriter() :
    os.system('clear')
    fps = FPS.get()
    frames = FPS.get()
    pbar = tqdm(total=frames)
    while True :
        if 0 in img_str :
            WH = img_str[0].shape
            break
    width_height = (WH[1],WH[0])
    fourcc = cv.VideoWriter_fourcc(*'mp4v')
    video = cv.VideoWriter(sys.path[0]+'/out.mp4',fourcc,fps,width_height,isColor=False)
    K = 0
    end = None
    while True :
        if END.full() :
            end = END.get()
        if K == end :
            video.release()
            print('文件保存在 :',sys.path[0]+'/out.mp4')
            break
        if K in img_str :
            video.write(img_str[K])
            del img_str[K]
            K+=1
            pbar.update(1)

if __name__ == '__main__' :
    mv_path = input('要处理的视频 :')
    #获取每一帧
    P=Process(target=cap_while,daemon=True,args=(cap_list,mv_path,END,FPS))
    P.start()
    #处理每一帧
    for _ in range(IMG2STR_CPU_COUNT) :
        Process(target=img2str,daemon=True,args=(cap_list,img_str)).start()
    #合成
    videowriter()


字符画转视频[Termux,Python]的评论 (共 条)

分享到微博请遵守国家法律