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

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

某些时候很容易让MM惊呼“被你装到了”,系不系很猴赛雷呀? 尤其最后一个,法国面具男的曳步舞,将视频转成ASCII符号形式跳舞。

我曾专门学过此视频的跳法,音乐一响,还是会跟着BGM律动! 它的背景杂物、色彩较多,转成ascii后影响人像效果。

怎么办呢?

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

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

废话不多说,上分享

第一个,AnimeGANv2人脸动漫化

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

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

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

来看看效果。

洪真英的漫画没本人好看,差评 🚗,效果还行,有点像某音AI绘画

第二个,美女素描图

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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可以下载它

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

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

或直接观看

完整脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# -*- 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的“人体分析”

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

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

  • 提取音频,moviepy库
  • 分割音频(分割成数个1分钟以内的音频),pydub库
  • 音频转文本,百度API的普通话语音识别

面具男ASCII曳步舞

  • 从视频中提取图片/合成视频/提取音频都用到ffmpeg ```py #将视频分割成图片 ffmpeg -i [输入文件名] -r [fps,帧率] [分割图存储路径]

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

#合成视频 ffmpeg -i [视频文件名] -i [音频文件名] -strict -2 -f mp4 [合并后的文件名] ```

  • 生成ascii图片用到PIL库的ImageDraw

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

Python Geek Tech wechat
欢迎订阅 Python 技术,这里分享关于 Python 的一切。