今天分享的这段代码,看起来没啥实际用处,而且有些反潮流,因为现如今大家看视频都追求更高分辨率的超清画质,而我们这个,是一个“超不清”的视频播放器

在控制台里播放视频,用字符来表示画面

不过我觉得它至少可以有三个作用:1.用来练习视频和图像处理的编程开发;2.在没有图形界面的服务器上播放视频(虽然效果不咋地);3.作为一种独特的艺术风格化处理

程序的原理其实很简单,关键是你要理解计算机中一张图像的组成:一堆像素点。我们平常说的 1920*1080 之类的分辨率,也就是指这个像素点的多少。我们想做成字符画,也就是考虑如何用不同的字符来表示一个像素。

通常一个像素点由3个0~255的值表示,分别表示红、绿、蓝三种颜色值,值越大表示颜色越深。但字符画是没有颜色的,所以需要将图像转成灰度图,这样就可以跟一组从深到浅的字符形成一种对应关系。比如深的点就是 @,浅色的点就是 .。

一幅图像全部转成字符序列后,就可以直接在控制台输出了。对于一个视频来说,只需要将每一帧都转换后输出,并按照一定的时间间隔清屏、输出下一帧,即可达到我们的需要的效果。

转换后的效果:

代码:

# coding: utf8
import cv2 as cv
import os
import time
# 替换字符列表
ascii_char = list(r"$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")char_len = len(ascii_char)
# 加载视频
cap = cv.VideoCapture('video.mp4')
while True:
   # 读取视频每一帧    hasFrame, frame = cap.read()
   if not hasFrame:
       break    # 视频长宽    width = frame.shape[0]    height = frame.shape[1]
   # 转灰度图    img_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
   # 缩小图片并调整长宽比    img_resize = cv.resize(img_gray, (int(width / 10), int(height / 10)))    text = ''    # 遍历图片中的像素    for row in img_resize:
       for pixel in row:
           # 根据像素值,选取对应的字符            text += ascii_char[int(pixel / 256 * char_len)]        text += '\n'    # 清屏    os.system('cls')  # mac是'clear'    # 输出生成的字符方阵    print(text)
   # 适当暂停一下    time.sleep(0.03)

代码不长,稍微解释下其中几处:

  1. ascii_char 这个字符序列并不是必须这样,只要大致上满足其中的字符看起来从深到浅即可,字符越多越准确,效果就越好。

  2. 读取视频使用了 opencv-python,并直接用它提供的方法转了灰度图,在之前的文章中也有过介绍:OpenCV-Python,计算机视觉开发利器

  3. resize 这一步比较重要,因为有的视频分辨率很高,直接一个像素转一个字符的话量太大,所以先缩小图片。另一个原因是字符一般都不是正方形,所以在图片长宽比上要做一定的调,这样最终效果比较好。(实际中要根据你自己控制台中的字体效果来调整缩放比例)

  4. ascii_char[int(pixel / 256 * char_len)] 是整个转换的核心,因为一个像素的颜色范围是 0~255,通过 pixel / 256 * char_len 可以将一个像素值对应于字符序列中灰度相当的字符

  5. 关于输出,有几个值得注意的点:输出一帧前需要清屏,不同平台命令有区别;时间间隔、控制台的字体大小、缩放比例都要根据实际情况作调整;如果计算时间过长、刷新太慢而屏幕闪烁,可以考虑进一步缩小图片,或者先将所以帧转换完毕后再统一输出。

最后请各位欣赏最终的视频效果:

https://v.qq.com/x/page/u0796m1ruzo.html

文中完整代码已上传,包括转单张图片转视频两份代码。
获取地址请在公众号“Crossin的编程教室”里回复关键字 播放器


©著作权归作者所有:来自51CTO博客作者mob604756ee87ff的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. Oracle如何使用spool导出utf8字符集的文本文件
  2. javascript数据类型转换
  3. Python3 常见数据类型的转换
  4. js 基础
  5. 搭建SpringBoot+dubbo+zookeeper+maven框架(四)
  6. Shell中截取字符串的用法小结
  7. Longest Substring Without Repeating Characters 解决思路
  8. 送你 31 道 JavaScript 面试题
  9. 代码分析平台CodeQL学习手记(二)

随机推荐

  1. Android渗透测试Android渗透测试入门教程
  2. 独立的android开发者开发app如何盈利
  3. Android知识图谱:我们到底需要学习哪些And
  4. Android最佳实践(六)之扫描二维码模块
  5. android app的类响应式设计
  6. Android Studio无法加载API帮助文档问题
  7. Unity3D 调用Android的提供的接口
  8. [自定义控件]android自定义view实战之太
  9. Android SDK 2.0安装(配置图文教程)
  10. Android 5.1和Android 5.0相比有哪些变化