最近几个月,毒教材被曝光引发争议,那些编写度教材的人着实可恶。咱程序员也没有手绘插画能力,但咱可以借助强大的深度学习模型将视频转动漫。所以今天的目标是让任何具有python语言基本能力的程序员,实现短视频转动漫效果。
效果展示
; 一、思路流程
- 读取视频帧
- 将每一帧图像转为动漫帧
- 将转换后的动漫帧转为视频
难点在于如何将图像转为动漫效果。这里我们使用基于深度学习的动漫效果转换模型,考虑到许多读者对这块不了解,因此我这边准备好了源码和模型,直接调用即可。不想看文章细节的可以直接拖到文章末尾,获取源码。
二、图像转动漫
为了让大家不关心深度学习模型,已经为大家准备好了转换后的onnx类型模型。接下来按顺序介绍运行onnx模型流程。
安装onnxruntime库
pip install onnxruntime
源码及Python资料教程、电子书领取群 279199867
如果想要用GPU加速,可以安装GPU版本的onnxruntime:
pip install onnxruntime-gpu
需要注意的是:
onnxruntime-gpu的版本跟CUDA有关联,具体对应关系如下:
当然,如果用CPU运行,那就不需要考虑那么多了。考虑到通用性,本文全部以CPU版本onnxruntime。
运行模型
先导入onnxruntime库,创建InferenceSession对象,调用run函数。
如下所示
import onnxruntime as rt
sess = rt.InferenceSession(MODEL_PATH)
inp_name = sess.get_inputs()[0].name
out = sess.run(None, {inp_name: inp_image})
具体到我们这里的动漫效果,实现细节如下:
import cv2
import numpy as np
import onnxruntime as rt
MODEL = "models/anime_1.onnx"
MODEL = "models/anime_2.onnx"
sess = rt.InferenceSession(MODEL)
inp_name = sess.get_inputs()[0].name
def infer(rgb):
rgb = np.expand_dims(rgb, 0)
rgb = rgb * 2.0 / 255.0 - 1
rgb = rgb.astype(np.float32)
out = sess.run(None, {inp_name: rgb})
out = out[0][0]
out = (out+1)/2*255
out = np.clip(out, 0, 255).astype(np.uint8)
return out
def preprocess(rgb):
pad_w = 0
pad_h = 0
h,w,__ = rgb.shape
N = 2**3
if h%N!=0:
pad_h=(h//N+1)*N-h
if w%2!=0:
pad_w=(w//N+1)*N-w
# print(pad_w, pad_h, w, h)
rgb = np.pad(rgb, ((0,pad_h),(0, pad_w),(0,0)), "reflect")
return rgb, pad_w, pad_h
其中, preprocess函数确保输入图像的宽高是8的整数倍。这里主要是因为考虑到深度学习模型有下采样,确保每次下采样能被2整除。
单帧效果展示
三、视频帧读取与视频帧写入
这里使用Opencv库,提取视频中每一帧并调用回调函数将视频帧回传。在将图片转视频过程中,通过定义VideoWriter类型变量WRITE确保唯一性。具体实现代码如下:
import cv2
from tqdm import tqdm
WRITER = None
def write_frame(frame, out_path, fps=30):
global WRITER
if WRITER is None:
size = frame.shape[0:2][::-1]
WRITER = cv2.VideoWriter(
out_path,
cv2.VideoWriter_fourcc(*'mp4v'), # 编码器
fps,
size)
WRITER.write(frame)
def extract_frames(video_path, callback):
video = cv2.VideoCapture(video_path)
num_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
for _ in tqdm(range(num_frames)):
_, frame = video.read()
if frame is not None:
callback(frame)
else:
break
完整源码获取点击 蓝色字体 获取哟~
给大家推荐一套爬虫教程,涵盖常见大部分案例,非常实用!
代码总是学完就忘记?100个爬虫实战项目!让你沉迷学习丨学以致用丨下一个Python大神就是你!
Original: https://www.cnblogs.com/hahaa/p/16583200.html
Author: 轻松学Python
Title: 如何用Python将普通视频变成动漫视频
相关阅读1
Title: ECharts循环push数据到series,从而实现series的动态处理之(一)(先用给定数据,后期用后端返回数据)
后续继续基于Flask+ECharts进行可视化研究
由于工作中要用到基于ECharts的大屏可视化数据展示,下方为自己先用静态数据进行的可视化效果图一角,逐步完善中......,后续会基于Python的Flask框架以及ajax传输数据,包括筛选各种条件后的数据对图形进行异步无刷新改变。。。。。。
嘻嘻,2年没有敲代码了,部分代码有进行算法练习,勿见怪哦......
效果图一角:
代码如下:
```html;gutter:true;
第一个 ECharts 实例
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
var data = [
['x轴', '60px','101npx','178xpx','289ypx'],
['西南航空', 60,101,178,289],
['国泰航空', 120,180,190,303],
['东方航空', 90,92,97,103]
]
console.log("我是源数据1data=====》",data)
/***
* @注意
* @以下纯属练习处理数据(原因2年没敲代码了,练习下,嘻嘻)
*/
var newAarry = []
for(var i=0;i<data.length;i++){
if(i!=0){
newAarry.push(data[i][0])
}
}
console.log("我是图例=====》",newAarry) //打印结果是 ['西南航空', '国泰航空', '东方航空']
var newData = []
console.log("我是源数据2data=====》",data)
for(var j=0;j<data.length;j++){
var news = data[j].slice(1)
//console.log("我是循环中的数据news=====》",news)
newData.push(news)
}
console.log("我是处理后的数据newData=====》",newData)
/***
* @注意
* @以下是有用数据,上方数据处理纯属练习处理数据(原因2年没敲代码了,练习下,嘻嘻)
*/
//循环往series里push数据
var series1 = []
var countMax = 0
for(var key in data){
console.log(data[key])
if(key!=0){
//去除第一行
series1.push(
{
name:data[key][0],//图例
type:'line',//折线 bar 饼状
data:data[key].splice(1)
}
)
}
countMax++;
}
console.log("我是动态的series=====》",series1)
// 指定图表的配置项和数据
var option = {
title:{text:'我是折线图'},
//图例
legend: {
orient:'vertical',
x:'right',
y:'center',
itemGap:25,
},
tooltip: {},
//dataset:{ source:newData},
// 声明一个 X 轴,类目轴(category)。默认情况下,类目轴对应到 dataset 第一列。
xAxis: {
type: 'category',
data: data[0].slice(1) //将x轴设定为对象数据第一列(去除第一个元素)
},
// 声明一个 Y 轴,数值轴。
yAxis: {},
// 声明多个 bar 系列,默认情况下,每个系列会自动对应到 dataset 的每一列。
series: series1
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
当然了,工作中的数据比这个复杂多了,这只是第一步已经完成了, **going......**
> Original: https://www.cnblogs.com/zmdComeOn/p/15914377.html
> Author: 子钦加油
> Title: ECharts循环push数据到series,从而实现series的动态处理之(一)(先用给定数据,后期用后端返回数据)
## **相关阅读2**
## Title: Python实战:截图识别文字,过万使用量版本!(附源码!!)
**前人栽树后人乘凉,以不造轮子为由**
**使用百度的图片识字功能,实现了一个上万次使用量的脚本。**
系统:win10
Python版本:python3.8.6
pycharm版本:pycharm 2021.1.2(Professional Edition)
**完整代码下载:[Baidu_Ocr.py-Python ;](https://download.csdn.net/download/qq_41224362/45807559?spm=1001.2014.3001.5503 "Baidu_Ocr.py-Python")**
![Python实战:截图识别文字,过万使用量版本!(附源码!!)](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20221111/1450099-20211127180327027-1924174824.gif)
![Python实战:截图识别文字,过万使用量版本!(附源码!!)](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20221111/1450099-20211127172112941-1430973143.png)
**一、获取百度智能云token**
[百度智能云](https://login.bce.baidu.com/?account=)登录后找到人工智能界面下的文字识别->管理界面创建应用文字识别。
![Python实战:截图识别文字,过万使用量版本!(附源码!!)](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20221111/1450099-20211127172716530-430162790.png)
创建应用完成后记录下,后台界面提供的AppID 、API key 、Secret Key 的信息
![Python实战:截图识别文字,过万使用量版本!(附源码!!)](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20221111/1450099-20211127172724407-345325066.png)
接下来根据 官方提供的文档获取使用Token
encoding:utf-8
import requests
client_id 为官网获取的AK, client_secret 为官网获取的SK
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=wgEHks0l6MCpalbs3lPuFX1U&client_secret=Z4Rn4ghBx9k06fUYPmSEIRbCFvWFxLyQ'
response = requests.get(host)
if response:
print(response.json()['access_token'])
![Python实战:截图识别文字,过万使用量版本!(附源码!!)](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20221111/1450099-20211127172917024-192984907.png)
**二、百度借口调用**
使用获取后token 调用百度接口对图片进行识别提取文字
encoding:utf-8
import requests
import base64
'''
通用文字识别(高精度版)
'''
request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic"
二进制方式打开图片文件
f = open('图片.png', 'rb')
img = base64.b64encode(f.read())
params = {"image":img}
获取后的Token的调用
access_token = '24.0d99efe8a0454ffd8d620b632c58cccc.2592000.1639986425.282335-24065278'
request_url = request_url + "?access_token=" + access_token
headers = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.post(request_url, data=params, headers=headers)
if response:
print (response.json())
获取后的token 为json 格式的数据
![Python实战:截图识别文字,过万使用量版本!(附源码!!)](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20221111/1450099-20211127173412984-647293142.png)
此处步骤我们可以看出识别后的文件是以json 的格式返回的所以要想达到取出文字的效果就需要对json 格式的返回值进行解析
**三、搭建窗口化的程序以便于使用**
实现窗口可视化的第三方类库是Tkinter 。可在终端输入pip install tkinter 自行下载安装
导入tkinter 模块包 构建我们的可视化窗口,要是实现的功能有截图识别文字,中英文分离,文字识别后自动发送给剪切板
from tkinter import *
创建窗口
window = Tk()
窗口名称
window.title('qcc-tnw')
设置窗口大小
window.geometry('400x600')
窗口标题设置
l=Label(window,text='百度API调用', bg='green', fg='white', font=('Arial', 12), width=30, height=2)
l.pack()
设置文本接收框
E1 = Text(window,width='100',height='100')
设置操作Button,单击运行文字识别 "window窗口,text表示按钮文本,font表示按钮本文字体,width表示按钮宽度,height表示按钮高度,command表示运行的函数"
img_txt = Button(window, text='文字识别', font=('Arial', 10), width=15, height=1)
设置操作Button,单击分割英文
cut_en = Button(window, text='英文分割', font=('Arial', 10), width=15, height=1)
设置操作Button,单击分割中文
cut_cn = Button(window, text='中文分割', font=('Arial', 10), width=15, height=1)
参数anchor='nw'表示在窗口的北偏西方向即左上角
img_txt.pack(anchor='nw')
cut_en.pack(anchor='nw')
cut_cn.pack(anchor='nw')
使得构建的窗口始终显示在桌面最上层
window.wm_attributes('-topmost',1)
window.mainloop()
![Python实战:截图识别文字,过万使用量版本!(附源码!!)](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20221111/1450099-20211127175209904-2079224923.png)
**四、实现截图的自动保存**
通过上述对百度接口的解析发现接口是不支持提取剪切板中的文件的
所以通过PIL 库截取的图片从剪切板保存到本地,在调用百度的接口实现图片中文字的识别
PIL 的安装 终端输入pip install PIL
from PIL import ImageGrab
取出剪切板的文件保存至本地
image = ImageGrab.grabclipboard()
s= 'xxx.png'
image.save(s)
百度接口调用
request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic"
f = open(s, 'rb')
img = base64.b64encode(f.read())
params = {"image": img}
access_token = '24.ee0e97cbc00530d449464a563e628b8d.2592000.1640228774.282335-24065278'
request_url = request_url + "?access_token=" + access_token
headers = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.post(request_url, data=params, headers=headers)
for i in response.json()['words_result']:
print(i['words'])
完成后可以使用qq 或微信等的截图功能截图并运行程序
![Python实战:截图识别文字,过万使用量版本!(附源码!!)](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20221111/1450099-20211127175556012-1900044351.gif)
**五、将识别到的文字输出显示在窗口文本框中并将文字发送到剪切板**
if response:
for i in response.json()['words_result']:
# 接受识别后的文本
E1.insert("insert", i['words'] + '\n')
E1.pack(side=LEFT)
# 将识别后的文字写入剪切板
pyperclip.copy(E1.get("1.0","end"))
![Python实战:截图识别文字,过万使用量版本!(附源码!!)](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20221111/1450099-20211127180307036-1883651564.gif)
**六、提取识别后文字中的中(英)文**
此处的判断相对简单将 **if len(''.join(re.findall(r'[A-Za-z]', i['words'])))**
E1.delete('1.0','end')
for i in response.json()['words_result']:
判断是否存在英文
if len(''.join(re.findall(r'[A-Za-z]', i['words']))):
#将识别正则过滤后的文本在文本框中显示
E1.insert("insert", i['words'] + '\n')
E1.pack(side=LEFT)
#复制到剪切板
pyperclip.copy(E1.get("1.0", "end"))
最后将方法封装为函数形式传递至我们定义好的窗口按钮中
设置操作Button,单击运行文字识别 "window窗口,text表示按钮文本,font表示按钮本文字体,width表示按钮宽度,height表示按钮高度,command表示运行的函数"
img_txt = Button(window, text='文字识别', font=('Arial', 10), width=15, height=1,command=img_all)
设置操作Button,单击分割英文
cut_en = Button(window, text='英文分割', font=('Arial', 10), width=15, height=1,command=img_en)
设置操作Button,单击分割中文
cut_cn = Button(window, text='中文分割', font=('Arial', 10), width=15, height=1,command=img_cn)
参数anchor='nw'表示在窗口的北偏西方向即左上角
img_txt.pack(anchor='nw')
cut_en.pack(anchor='nw')
cut_cn.pack(anchor='nw')
window.wm_attributes('-topmost',1)
Auto Copied
Auto Copied
> Original: https://www.cnblogs.com/t-dashuai/p/15612623.html
> Author: 佟大帅
> Title: Python实战:截图识别文字,过万使用量版本!(附源码!!)
## **相关阅读3**
## Title: Python小游戏——外星人入侵(保姆级教程)第一章 09重构check_events()
## 系列文章目录
### 第一章:武装飞船
#### 09重构check_events()
## 一、重构
### 1.重构原因
随着游戏的开发,方法_check_events()将越来越长。因此将其部分代码放在两个方法中,其中一个处理KEYDOWN事件,另一个处理KEYUP事件:
### 2.重构的方法
我们创建了两个新的辅助方法:_check_keydown_events()和_check_keyup_events()。它们都包含形参self和event。这两个方法的代码是从_check_events()中复制而来的,因此将方法_check_events()中相应的代码替换成了对这两个新方法的调用。现在,方法_check_events()更简单,代码结构也更清晰,在其中响应玩家输入时将更容易。
## 二、代码及演示
### 1.修改game_functions
> 修改文件:game_functions.py
点击查看代码
渗透小红帽python的学习之路
外星人入侵小游戏
game_functions.py
存储让游戏运行的函数
import sys
import pygame
响应键盘函数
def check_keydown_events(event,ship):
if event.key == pygame.K_RIGHT:
# 移动飞船
ship.moving_right = True
# 玩家按下右箭头键时标志设为true
elif event.key == pygame.K_LEFT:
ship.moving_left = True
# 玩家按下左箭头键时标志设为true
响应松开按键的函数
def check_keyup_events(event,ship):
if event.key == pygame.K_RIGHT:
ship.moving_right = False
# 玩家松开右箭头键时标志设为false
elif event.key == pygame.K_LEFT:
ship.moving_left = False
# 玩家松开左箭头键时标志设为false
def check_events(ship): # 在玩家按右箭头时需要将飞船向右移动,
# 所以给函数加上了形参ship
for event in pygame.event.get(): # 监听键盘和鼠标事件
if event.type == pygame.QUIT:
sys.exit()
#修改alien_invasion.py,使其导入game_functions
#并将事件循环替换为对函数check_events()的调用
elif event.type == pygame.KEYDOWN:
check_keydown_events(event,ship)
elif event.type == pygame.KEYUP:
check_keyup_events(event,ship)
def update_screen(ai_settings,screen,ship):
# 将更新屏幕的代码移到此处
screen.fill(ai_settings.bg_color) # 每次循环都会重绘屏幕
ship.blitme() # 每次循环时重新绘制飞船
pygame.display.flip() # 让最近绘制的屏幕可见
飞船移动功能编写完毕
```
2.运行效果
飞船可以任意向左向右移动,直到移动到游戏界面边界时停止。
点击下方链接观看运行效果视频
有什么不懂的地方在评论区留言哦!希望我的文章能对你有所帮助,如果喜欢我的文章,请点赞收藏并关注!你的认可是对我创作最大的鼓励!
2022-08-24 19:38:53 星期三
Original: https://www.cnblogs.com/Penetration-redhat/p/16621359.html
Author: 渗透小红帽
Title: Python小游戏——外星人入侵(保姆级教程)第一章 09重构check_events()