欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于Python实现视频转字符画动漫小工具

程序员文章站 2022-03-08 19:12:39
目录导语正文一、准备中二、原理简介三、代码演示四、效果展示导语​哈喽!boys and  girls 我是每天疯狂赶代码的木木子~今天带大家来点儿好玩儿的东西,我想你们肯定是喜欢的!上面这个大家都认识...

导语

​哈喽!boys and  girls 我是每天疯狂赶代码的木木子~

今天带大家来点儿好玩儿的东西,我想你们肯定是喜欢的!

基于Python实现视频转字符画动漫小工具

上面这个大家都认识吧

对,就是字符动画啦,之前也是不是再那个旮旯里面看见过,但是还没上手自己试的。

小编给大家先试试效果了,效果也是真不错,趣味性蛮强滴 推荐指数5颗星,大家都开始动手

燥起来吧~

那么如何将视频动画转成字符画呢?今天就来教大家怎么转换,非常简单,今天教大家制作的

这款工具就能一键转换!

基于Python实现视频转字符画动漫小工具

正文

一、准备中

1)素材的话可以自己找一小段视频的哈。

2)环境安装

本文用到的环境如下:python3、pycharm、numpy、cv2以及部分自带模块。

模块安装:

pip install -i https://pypi.douban.com/simple/ +模块名

二、原理简介

1)视频转为一帧帧的图片这个利用opencv就可以实现了。

2)**将每帧图片转为字符画,**原理是根据图片的像素值确定每个像素点用什么字符。

3)按顺序播放字符画即可。

三、代码演示

# 视频转字符动画
import os
import cv2
import sys
import time
import ctypes
import subprocess
import numpy as np


# 暗蓝色
foreground_darkblue = 0x01
# 暗绿色
foreground_darkgreen = 0x02
# 暗天蓝色
foreground_darkskyblue = 0x03
# 暗红色
foreground_darkred = 0x04
# 暗粉红色
foreground_darkpink = 0x05
# 暗黄色
foreground_darkyellow = 0x06
# 暗白色
foreground_darkwhite = 0x07
# 暗灰色
foreground_darkgray = 0x08
# 蓝色
foreground_blue = 0x09
# 绿色
foreground_green = 0x0a
# 天蓝色
foreground_skyblue = 0x0b
# 红色
foreground_red = 0x0c
# 粉红色
foreground_pink = 0x0d
# 黄色
foreground_yellow = 0x0e
# 白色
foreground_white = 0x0f
# 上面颜色对应的rgb值
cmd_colors = {
				'foreground_darkblue': [foreground_darkblue, (0, 0, 139)],
				'foreground_darkgreen': [foreground_darkgreen, (0, 100, 0)],
				'foreground_darkskyblue': [foreground_darkskyblue, (2, 142, 185)],
				'foreground_darkred': [foreground_darkred, (139, 0, 0)],
				'foreground_darkpink': [foreground_darkpink, (231, 84, 128)],
				'foreground_darkyellow': [foreground_darkyellow, (204, 204, 0)],
				'foreground_darkwhite': [foreground_darkwhite, (255, 250, 250)],
				'foreground_darkgray': [foreground_darkgray, (169, 169, 169)],
				'foreground_blue': [foreground_blue, (0, 0, 255)],
				'foreground_green': [foreground_green, (0, 128, 0)],
				'foreground_skyblue': [foreground_skyblue, (135, 206, 235)],
				'foreground_red': [foreground_red, (255, 0, 0)],
				'foreground_pink': [foreground_pink, (255, 192, 203)],
				'foreground_yellow': [foreground_yellow, (255, 255, 0)],
				'foreground_white': [foreground_white, (255, 255, 255)]
			}
chars = " .,-'`:!1+*abcdefghijklmnopqrstuvwxyz<>()\/{}[]?234567890abcdefghijklmnopqrstuvwxyz%&@#$"


'''
function:
	视频转图片
input:
	-videopath: 视频路径
	-size: 指定图片大小
	-interval: 视频每interval帧取一帧
return:
	-img_list: 图像列表
'''
def video2imgs(videopath, size, interval=1):
	img_list = list()
	capture = cv2.videocapture(videopath)
	i = -1
	while capture.isopened():
		i += 1
		ret, frame = capture.read()
		if ret:
			if i % interval == 0:
				# frame = cv2.cvtcolor(frame, cv2.color_bgr2gray)
				img = cv2.resize(frame, size, interpolation=cv2.inter_area)
				img_list.append(img)
		else:
			break
	capture.release()
	return img_list


'''
# 根据距离将图片的rgb值转为windows-cmd窗口支持的颜色
def rgb2cmdcolor(color):
	cmd_color = none
	min_distance = 1e6
	for key, value in cmd_colors.items():
		distance = np.square(np.array(color) - np.array(value[1])).sum()
		if distance < min_distance:
			min_distance = distance
			cmd_color = value[0]
	return cmd_color
'''


'''
function:
	图像转字符画
input:
	-img(np.array): 图像
return:
	-img_chars: 像素点对应的字符集合
'''
def img2chars(img):
	img_chars = []
	height, width, channel = img.shape
	for row in range(height):
		line = ""
		for col in range(width):
			percent = int(np.array(img[row][col]).sum() / 3) / 255
			char_idx = int(percent * (len(chars) - 1))
			line += chars[char_idx] + ' '
		img_chars.append(line)
	return img_chars


'''
function:
	视频转字符画s
input:
	-imgs: 视频里捕获的所有图片
return:
	-video_chars: img_chars的集合
'''
def imgs2chars(imgs):
	video_chars = []
	for img in imgs:
		video_chars.append(img2chars(img))
	return video_chars


'''
function:
	播放字符画s
input:
	-video_chars: imgs2chars中获取的video_chars
	-iscmd(bool): 是否在windows的cmd窗口播放
	-color: 颜色选择, cmd中有效
'''
def play(video_chars, color=none, iscmd=true):
	if color and iscmd:
		std_output_handle = -11
		std_out_handle = ctypes.windll.kernel32.getstdhandle(std_output_handle)
		color_choice = none
		if color.isdigit():
			color_choice = list(cmd_colors.values())[int(color)][0]
		else:
			color_choice = cmd_colors.get(color)[0]
		if color_choice is not none:
			_ = ctypes.windll.kernel32.setconsoletextattribute(std_out_handle, color_choice)
	width, height = len(video_chars[0][0]), len(video_chars[0])
	for img_chars in video_chars:
		for row in range(height):
			print(img_chars[row])
		time.sleep(1/24)
		if iscmd:
			os.system('cls')
		else:
			subprocess.call("clear")


# 主函数
def main(videopath, color=none, iscmd=true):
	imgs = video2imgs(videopath=videopath, size=(64, 48), interval=1)
	video_chars = imgs2chars(imgs)
	input("[info]: complete pre-processing! enter <enter> button to start to play...")
	if iscmd:
		os.system('cls')
	else:
		subprocess.call("clear")
	play(video_chars, color=color, iscmd=true)


if __name__ == '__main__':
	import argparse
	parser = argparse.argumentparser()
	parser.add_argument('-f', '--file', help='video file.')
	parser.add_argument('-c', '--color', help='color for playing.')
	args = parser.parse_args()
	main(args.file, color=args.color)

四、效果展示

1)截图效果展示

第一组随机截图:

基于Python实现视频转字符画动漫小工具

基于Python实现视频转字符画动漫小工具

​第二组随机截图:

基于Python实现视频转字符画动漫小工具

基于Python实现视频转字符画动漫小工具

第三组随机截图:

基于Python实现视频转字符画动漫小工具

以上就是基于python实现视频转字符画动漫小工具的详细内容,更多关于python视频转字符画的资料请关注其它相关文章!