zoukankan      html  css  js  c++  java
  • python图像、视频转字符画

      python图像转字符画需要用到matplotlib.pyplot库,视频转字符画需要用到opencv库,这里的代码基于python 3.5

      图像转字符画需要先将图像转为灰度图,转灰度图的公式是 gray = 0.2126 * r + 0.7152 * g + 0.0722 * b,因为matplotlib图像的色彩排序是RGB的(opencv是BGR),所以如果不用库函数,可以使用以下代码实现灰度转换:

    gray = 0.2126 * pic[:,:,0] + 0.7152 * pic[:,:,1] + 0.0722 * pic[:,:,2]

      转成灰度图以后,对于每一个像素值,都要对应一个字符值。然后从图像中均匀取一些像素出来作映射即可实现图像到字符画的转换,代码如下:

    import matplotlib.pyplot as plt
    show_heigth = 30              
    show_width = 40
    #这两个数字是调出来的
    
    ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,"^`'. ")
    #生成一个ascii字符列表
    char_len = len(ascii_char)
    
    pic = plt.imread("wm.jpg")
    #使用plt.imread方法来读取图像,对于彩图,返回size = heigth*width*3的图像
    #matplotlib 中色彩排列是R G B
    #opencv的cv2中色彩排列是B G R
    
    pic_heigth,pic_width,_ = pic.shape
    #获取图像的高、宽
    
    gray = 0.2126 * pic[:,:,0] + 0.7152 * pic[:,:,1] + 0.0722 * pic[:,:,2]
    #RGB转灰度图的公式 gray = 0.2126 * r + 0.7152 * g + 0.0722 * b
    
    #思路就是根据灰度值,映射到相应的ascii_char
    for i in range(show_heigth):
        #根据比例映射到对应的像素
        y = int(i * pic_heigth / show_heigth)
        text = ""
        for j in range(show_width):
            x = int(j * pic_width / show_width)
            text += ascii_char[int(gray[y][x] / 256 * char_len)]
        print(text)

    效果:

      对于视频,其实也就是将每一帧转成字符画,这里用opencv来读取视频的每一帧。

      如果没有装opencv库的话,可以先去https://www.lfd.uci.edu/~gohlke/pythonlibs/下载对应版本的opencv,然后安装

      如果遇到numpy core的问题,可以更新一下numpy。

      为了有更好的显示效果,先将每一帧的转换的字符画保存下来,最后再统一输出出去。

    import cv2
    import os
    show_heigth = 30              
    show_width = 80
    
    ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,"^`'. ")
    #生成一个ascii字符列表
    char_len = len(ascii_char)
    
    vc = cv2.VideoCapture("v.mkv")          #加载一个视频
    
    if vc.isOpened():                       #判断是否正常打开
        rval , frame = vc.read()
    else:
        rval = False
        
    frame_count = 0
    outputList = []                         #初始化输出列表
    while rval:   #循环读取视频帧  
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  #使用opencv转化成灰度图
        gray = cv2.resize(gray,(show_width,show_heigth))#resize灰度图
        text = ""
        for pixel_line in gray:
            for pixel in pixel_line:                    #字符串拼接
                text += ascii_char[int(pixel / 256 * char_len )]
            text += "
    "                                
        outputList.append(text)
        frame_count = frame_count + 1                           
        if frame_count % 100 == 0:
            print("已处理" + str(frame_count) + "")
        rval, frame = vc.read()  
    print("处理完毕")
    
    for frame in outputList:            
        os.system("cls")                    #清屏
        print(frame)
        print()
        print()

     这里用的bad apple的视频来进行转换:

  • 相关阅读:
    直接初始化和复制初始化
    C++ 内连接与外连接 (转)
    mysql-Innodb事务隔离级别-repeatable read详解(转)
    Linux操作系统多线程信号总结
    Keil MDK 5.14 仿真时System Viewer菜单显示空白和Peripherals菜单无外设寄存器
    转载傅里叶级数和傅里叶变换的理解 https://www.cnblogs.com/h2zZhou/p/8405717.html
    SPI总线的原理与Verilog实现
    SD 模拟sip 读写子程序
    SD卡 模拟SPI总线控制流程
    SD卡spi读写流程
  • 原文地址:https://www.cnblogs.com/youmuchen/p/8299109.html
Copyright © 2011-2022 走看看