OPENCV将视频转换为图像帧并且进行ASCII码的转换

该博客介绍了一种使用Python将视频转换为ASCII字符动画的方法。首先通过OpenCV将视频拆分成帧图像,然后将图像转换为ASCII字符,最后将处理过的字符图像合成为新的视频。整个过程涉及视频读取、图像处理、字符映射和视频编码等技术。
摘要由CSDN通过智能技术生成

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

众所周知,每段视频是由一帧帧图像构成,Opencv处理视频图像信息的原理就是将视频转为一帧帧的图像,将图像帧根据需求进行处理后,再将图像帧处理转换为视频,即可达到处理视频的目的。

本实验我们将需要处理的视频准备好了后,利用Python的一系列库函数如Opencv,将视频转换为一批帧图像,再通过代码函数对帧图像的像素进行处理,将其转换为字符串,最后将所有处理好的帧图像转换为视频进行播放,即可达到视频处理的目的。。

本案例的实现过程主要分为以下几步

1.导入数据
2.导入库函数;
3.将视频转化为图像帧;
4.对图片帧进行ASCII码的转换;
5.将转换好的图片帧合成视频;

案例实现代码

1.导入数据

```

!wget -N https://cnnorth4-modelhub-datasets-obsfs-sfnua.obs.cn-north-4.myhuaweicloud.com/content/35d24c0e-f337-442b-935f-ef8123062d3e/QzNm9F/dataset/test_demo0510.mp4 ```

2.导入库函数

```

导入Python库

import cv2 from PIL import Image,ImageFont,ImageDraw import os from cv2 import VideoWriter, VideoWriter_fourcc, imread, resize ```

3.将视频转化为图像帧

```

将视频转换为图片存入目标文件夹

​ def videotopic(vp):   number = 0       # 判断载入的视频是否可以打开   if vp.isOpened():               #r:布尔型 (True 或者False),代表有没有读取到图片,frame:表示截取到的一帧的图片的数据,是个三维数组       r,frame = vp.read()               #判断文件夹是否存在,不存在的话则新建文件夹       if not os.path.exists('cachepic'):           os.mkdir('cachepic')       os.chdir('cache_pic')           else:       r = False           #遍历视频,并将每一帧图片写入文件夹   while r:       number += 1       cv2.imwrite(str(number)+'.jpg',frame)       r,frame = vp.read()           print('\n由视频一共生成了{}张图片!'.format(number))       # 修改当前工作目录至主目录   os.chdir("..")   return number ```

4.对图片帧进行ASCII码的转换

```

将图片进行批量化处理

​ def startochar(number, savepicpath):       #判断文件夹是否存在,不存在的话则新建文件夹   if not os.path.exists('cachechar'):       os.mkdir('cachechar') ​   # 生成目标图片文件的路径列表   imgpathlist = [savepicpath + r'/{}.jpg'.format(i) for i in range(1, number + 1)]   task = 0 ​   for imagepath in imgpathlist:               # 获取图片的分辨率       imgwidth, imgheight = Image.open(imagepath).size       task += 1 ​       #处理图片,并显示处理进程       imgtochar(imagepath, imgwidth, img_height, task)               print('{}/{} is processed.'.format(task, number))           print('=======================')   print('All pictures were processed!')   print('=======================')   return 0 ​

将图片转换为灰度图像后进行ascii_char中的ASCII值输出

函数输入像素RGBA值,输出对应的字符码。其原理是将字符均匀地分布在整个灰度范围内,像素灰度值落在哪个区间就对应哪个字符码。

​ def getchar(r, g, b, alpha=256):       #asciichar就是字符列表,用来将不同灰度的像素进行不同字符体替换的参照。   asciichar = list("#RMNHQODBWGPZ*@$C&98?32I1>!:-;. ")       #alpha在为0的时候便是完全透明的图片,所以返回空   if alpha == 0:       return ''       length = len(asciichar)       #转为灰度图   #RGBA是代表Red(红色)、Green(绿色)、Blue(蓝色)和Alpha的色彩空间,Alpha通道一般用作不透明度参数   #如果一个像素的alpha通道数值为0%,那它就是完全透明的,而数值为100%则意味着一个完全不透明的像素       gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)   # unit = (256.0 + 1) / len(asciichar)   unit = 256 / len(asciichar)   return asciichar[int(gray / unit)] ​ ​ def imgtochar(imagepath, rawwidth, rawheight, task):   width = int(rawwidth / 6)   height = int(rawheight / 15) ​   # 以RGB模式打开   im = Image.open(imagepath).convert('RGB')   im = im.resize((width, height), Image.NEAREST) ​   txt = ''   color = []       #遍历图片的每个像素   for i in range(height):       for j in range(width):           pixel = im.getpixel((j, i)) ​           # 将颜色加入进行索引           color.append((pixel[0], pixel[1], pixel[2]))           if len(pixel) == 4:               txt += getchar(pixel[0], pixel[1], pixel[2], pixel[3])           else:               txt += getchar(pixel[0], pixel[1], pixel[2])       txt += '\n'       color.append((255, 255, 255)) ​   imtxt = Image.new("RGB", (rawwidth, rawheight), (255, 255, 255))   dr = ImageDraw.Draw(imtxt)   font = ImageFont.loaddefault().font   x, y = 0, 0   fontw, fonth = font.getsize(txt[1])   fonth *= 1.37 # 调整字体大小   for i in range(len(txt)):       if (txt[i] == '\n'):           x += fonth           y = -fontw       dr.text((y, x), txt[i], fill=color[i])       y += fontw           #存储处理后的图片至文件夹   os.chdir('cachechar')   imtxt.save(str(task) + '.jpg') ​   #直接进入新创建的文件夹将生成的图片直接存入文件夹中   os.chdir("..")   return 0 ```

5.将转换好的图片帧合成视频

```

进度条显示

def processbar(percent, startstr='', endstr='', totallength=0):   bar = ''.join("■ " * int(percent * totallength)) + ''   bar = '\r' + startstr + bar.ljust(totallength) + ' {:0>4.1f}%|'.format(percent * 100) + endstr   print(bar, end='', flush=True) ​

图片帧合成视频

​ def jpgtovideo(charimagepath, FPS):       # 设置视频编码器,这里使用MP42编码器   videofourcc = VideoWriterfourcc(*"MP42") ​   # 生成目标字符图片文件的路径列表   charimgpathlist = [charimagepath + r'/{}.jpg'.format(i) for i in range(1, number + 1)] ​   # 获取图片的分辨率   charimgtest = Image.open(charimgpathlist[1]).size   if not os.path.exists('video'):       os.mkdir('video')   videowritter = VideoWriter('video/output.avi', videofourcc, FPS, charimgtest)   sum = len(charimgpathlist)   count = 0   for imagepath in charimgpathlist:       img = cv2.imread(imagepath)       videowritter.write(img)       endstr = '100%'       count = count + 1       processbar(count / sum, startstr='', endstr=endstr, totallength=15) ​   videowritter.release()   print('\n')   print('=======================')   print('The video is finished!')   print('=======================') ```

主函数

```

初始视频路径

videopath = 'testdemo0510.mp4' ​

原始视频转为图片的图片保存路径

savepicpath = 'cache_pic' ​

图片经处理后的图片保存路径

savecharpicpath = 'cache_char' ​

读取视频

vp = cv2.VideoCapture(video_path) ​

将视频转换为图片 并进行计数,返回总共生成了多少张图片

number = videotopic(vp) ​

计算视频帧数

FPS = vp.get(cv2.CAPPROPFPS) ​

将图像进行字符串处理后

startochar(number, savepicpath) ​ vp.release() ​

将图片合成为视频

jpgtovideo(savecharpicpath, FPS) ```

视频播放

import cv2
from IPython.display import clear_output, Image, display

def show_video(video_path, show_text):
    video = cv2.VideoCapture(video_path)

    while True:
        try:
            clear_output(wait=True)
            # 读取视频
            ret, frame = video.read()
            if not ret:
                break
            height, width, _ = frame.shape
            cv2.putText(frame, show_text, (0, 100), cv2.FONT_HERSHEY_TRIPLEX, 3.65, (255, 0, 0), 2)
            frame = cv2.resize(frame, (int(width / 2), int(height / 2)))
        _, ret = cv2.imencode('.jpg', frame)

            display(Image(data=ret))

        except KeyboardInterrupt:
            video.release()

#视频循环播放
i=1
while i>0:
    show_video('video/output.avi',str(i))
    i=i+1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宋小童

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值