快看!法国面具男ASCII符号舞来了!

快看!法国面具男ASCII符号舞来了!_第1张图片

文 | ssw

来源:Python 技术「ID: pythonall」

9abd9769f6de3dca6a432f33fdbd1bc8.jpeg

分享几个处理图片、视频的工具和脚本,

某些时候很容易让MM惊呼“被你装到了”,系不系很猴赛雷呀?

快看!法国面具男ASCII符号舞来了!_第2张图片

尤其最后一个,法国面具男的曳步舞,将视频转成ASCII符号形式跳舞。

我曾专门学过此视频的跳法,音乐一响,还是会跟着BGM律动!

快看!法国面具男ASCII符号舞来了!_第3张图片

它的背景杂物、色彩较多,转成ascii后影响人像效果。

怎么办呢?

这次终于使用上了剪映,可以用它的“智能抠像”去除视频背景只留人像,

然后转成ascii人物动作就清晰多了:

快看!法国面具男ASCII符号舞来了!_第4张图片

废话不多说,上分享

第一个,AnimeGANv2人脸动漫化

AnimeGANv2基于PyTorch(一个深度学习框架),

安装Pytorch比其它麻烦,就不入坑了。

可以电脑打开在线版:https://huggingface.co/spaces/akhaliq/AnimeGANv2 ,无需本地安装框架,直接就可以进行转换。

来看看效果。

洪真英的漫画没本人好看,差评

快看!法国面具男ASCII符号舞来了!_第5张图片

,效果还行,有点像某音AI绘画

快看!法国面具男ASCII符号舞来了!_第6张图片

第二个,美女素描图

基于OpenCV库,安装命令pip install opencv-python

python技术公众号介绍过,就不贴链接了

快看!法国面具男ASCII符号舞来了!_第7张图片

So beautiful !比前面的动漫更具朦胧美,我比较喜欢美女身上这件外套。

快看!法国面具男ASCII符号舞来了!_第8张图片

import cv2
img = cv2.imread("h3.jpg")

#转换为灰度图片
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#将灰度图像反转
inverted_image = 255 - gray_img

#将反转的图像进行高斯模糊处理,再将模糊的图像倒置
blurred = cv2.GaussianBlur(inverted_image, (21, 21), 0)
inverted_blurred = 255 - blurred

#将灰度图像除以倒置的模糊图像,创建铅笔草图
pencil_sketch = cv2.divide(gray_img, inverted_blurred, scale=256.0)

#显示图片
cv2.imshow('original',img)
cv2.imshow("i love hongzhenying", pencil_sketch)
cv2.waitKey(0)
cv2.destroyAllWindows()

法国面具男ASCII舞蹈

运行脚本后,导入ascii视频和原视频到剪映中,设置画中画效果。

完工后的画中画视频有点大,100多M,我已上传到linux服务器,you-get可以下载它

you-get http://ssw.fit/free/mask_.mp4

# 买的服务器带宽限制4Mbps,估计下载速度500kB/s左右

或直接观看

完整脚本

# -*- coding:utf-8 -*-
from PIL import Image, ImageDraw, ImageFont
import numpy as np
import os
import sys
import shutil
class Video2Ascii:
    def __init__(self, filename):
        # 执行前的一些判断
        if not os.path.isfile(filename):
            print("源文件找不到,或者不存在!")
            exit()
        temp_arr = filename.split('.')
        # 字符列表,从左至右逐渐变得稀疏,对应着颜色由深到浅
        self.ascii_char = list("$@B%8&WM#*oahkbdpqwO0QLCJYXzcvunxrjft/\|()1[]?-_+~<>i!......... ")
        # 传入视频文件名
        self.filename = filename
        # 输出视频文件名
        self.outname = temp_arr[0] + "_out." + temp_arr[1]
        # 存储图片的临时路径、输出路径
        self.pic_path = 'temp_pic'
        self.ascii_path = 'temp_ascii'
        self.outpath = 'temp_out'
        # 设置图片缩小的倍数
        self.resize_times = 6
        # 设置输出文件的名字,声音文件以及带声音的输出文件
        self.mp3ilename = os.path.join(self.outpath, temp_arr[0] + '.mp3')
        self.mp4filename = os.path.join(self.outpath, self.outname)
        # 合并输出的视频文件
        self.mergefilename = os.path.join(self.outpath, temp_arr[0] + '_voice.' + temp_arr[1])
    # [1]、创建存储临时图片的路径
    def createpath(self):
        print("-" * 30)
        print("[1/6]正在创建临时路径...")
        print("-" * 30 + '\r\n')
        # 源视频文件的图片路径
        if not os.path.exists(self.pic_path):
            os.makedirs(self.pic_path)
        else:
            # 清空在创建
            shutil.rmtree(self.pic_path)
            os.makedirs(self.pic_path)
        # 转换之后的图片路径
        if not os.path.exists(self.ascii_path):
            os.makedirs(self.ascii_path)
        else:
            # 清空再创建
            shutil.rmtree(self.ascii_path)
            os.makedirs(self.ascii_path)
        # 存储输出文件的目录
        if not os.path.exists(self.outpath):
            os.makedirs(self.outpath)
    # [2]、将视频分割成图片
    def video2pic(self):
        print("-" * 30)
        print("[2/6]正在切割原始视频为图片...")
        print("-" * 30 + '\r\n')
        # 使用ffmpeg切割图片,命令行如下
        cmd = 'ffmpeg -i {0} -r 24 {1}/%06d.jpeg'.format(self.filename, self.pic_path)
        # 执行命令
        os.system(cmd)
    # [3]、将图片缩放、转成ascii形式
    def pic2ascii(self):
        print("-" * 30)
        print("[3/6]正在处理分析图片,转成ascii形式...")
        print("-" * 30 + '\r\n')
        # 读取原始图片目录
        pic_list = sorted(os.listdir(self.pic_path))
        total_len = len(pic_list)
        count = 1
        # 遍历每张图片
        for pic in pic_list:
            # 图片完整路径
            imgpath = os.path.join(self.pic_path, pic)
            # 1、缩小图片,转成灰度模式,存入数组
            origin_img = Image.open(imgpath)
            # 缩小之后宽高
            resize_width = int(origin_img.size[0] / self.resize_times)
            resize_height = int(origin_img.size[1] / self.resize_times)
            resize_img = origin_img.resize((resize_width, resize_height), Image.ANTIALIAS).convert("L")
            img_arr = np.array(resize_img)
            # 2、新建空白图片(灰度模式、与原始图片等宽高)
            new_img = Image.new("L", origin_img.size, 255)
            draw_obj = ImageDraw.Draw(new_img)
            font = ImageFont.truetype("arial.ttf", 8)
            # 3、将每个字符绘制在 8*8 的区域内
            for i in range(resize_height):
                for j in range(resize_width):
                    x, y = j*self.resize_times, i*self.resize_times
                    index = int(img_arr[i][j]/4)
                    draw_obj.text((x, y), self.ascii_char[index], font=font, fill=0)
            # 4、保存字符图片
            new_img.save(os.path.join('temp_ascii', pic), "JPEG")
            print("已生成ascii图(%d/%d)" % (count, total_len))
            count += 1
            # exit()
    # [4]、合成视频
    def ascii2video(self):
        print("-" * 30)
        print("[4/6]正在合成视频...")
        print("-" * 30 + '\r\n')
        # 输出视频保存路径
        savepath = os.path.join(self.outpath, self.outname)
        cmd = 'ffmpeg -threads 2 -start_number 000001 -r 24 -i {0}/%06d.jpeg -vcodec mpeg4 {1}'.format(self.ascii_path, savepath)
        os.system(cmd)
    # [5]、获取原始视频的mp3文件
    def video2mp3(self):
        print("-" * 30)
        print("[5/6]正在分离音频文件...")
        print("-" * 30 + '\r\n')
        # mp3名字和保存路径
        name = self.filename.split('.')[0] + '.mp3'
        savepath = os.path.join(self.outpath, name)
        cmd = 'ffmpeg -i {0} -f mp3 {1}'.format(self.filename, savepath)
        os.system(cmd)
    # [6]、将视频和音频合并
    def mp4andmp3(self):
        print("-"*30)
        print("[6/6]正在合并视频和音频...")
        print("-" * 30 + '\r\n')
        cmd = 'ffmpeg -i {0} -i {1} -strict -2 -f mp4 {2}'.format(self.mp4filename, self.mp3ilename,  self.mergefilename)
        os.system(cmd)
    # [0]、启动
    def start(self):
        """
            > 程序流程:
                1、创建路径
                2、将原始视频分割成图片
                3、将图片缩放、转成ascii形式
                4、将ascii形式的图片合成视频
                5、获取音频mp3文件
                6、合并视频和音频文件
        :return:
        """
        self.createpath()
        self.video2pic()
        self.pic2ascii()
        self.ascii2video()
        self.video2mp3()
        self.mp4andmp3()
        print("程序执行完成")
if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("参数不匹配,请参考(脚本名 原始视频):xxx.py test.mp4 ")
        exit()
    demo = Video2Ascii(sys.argv[1])
    demo.start()

总结

最近写的二篇文章都跟视频和图像有关,

加上这篇ASCII舞蹈,很容易混淆,这里简要总结下它们用到的库

用python做一个漂亮女生词云舞蹈视频

  • 从视频中提取图片,opencv-python库

  • 分割人像,百度API的“人体分析”

快看!法国面具男ASCII符号舞来了!_第9张图片

人体分析有一些瑕疵,面具男身后的旗子给识别进去了

用 Python 轻松将懂车帝视频转换为文本

  • 提取音频,moviepy库

  • 分割音频(分割成数个1分钟以内的音频),pydub库

  • 音频转文本,百度API的普通话语音识别

面具男ASCII曳步舞

  • 从视频中提取图片/合成视频/提取音频都用到ffmpeg

#将视频分割成图片
ffmpeg -i [输入文件名] -r [fps,帧率] [分割图存储路径]

#提取音频
ffmpeg -i [输入视频文件名] -f mp3 [输出的mp3文件名]

#合成视频
ffmpeg -i [视频文件名] -i [音频文件名] -strict -2 -f mp4 [合并后的文件名]
  • 生成ascii图片用到PIL库的ImageDraw

以上就是今天分享的内容,希望你能喜欢!

PS:Python技术交流群(技术交流、摸鱼、白嫖课程为主)又不定时开放了,感兴趣的朋友,可以在下方公号内回复:666,即可进入,一起 100 天计划!

快看!法国面具男ASCII符号舞来了!_第10张图片

老规矩,酱友们还记得么,右下角的 “在看” 点一下,如果感觉文章内容不错的话,记得分享朋友圈让更多的人知道!

cf0f10cc63df99bfec6b5c635816e6ec.gif

神秘礼包获取方式

识别二维码,回复:1024

快看!法国面具男ASCII符号舞来了!_第11张图片

你可能感兴趣的:(opencv,python,计算机视觉,人工智能,开发语言)