当前位置: 首页 > news >正文

微信公众号登录手机版镇江搜索优化技巧

微信公众号登录手机版,镇江搜索优化技巧,建设商城网站的书籍钱,樟树网站建设该程序改良自GitHub开源项目VideoCharDraw 在源程序CharDraw_thread.py 带压缩和多线程版本字符画的基础上使用Tkinter库添加了图形化的操作,使用户操作体验更方便。 什么是视频字符画? 视频转字符画是一种将视频中的每一帧图像转换为由字符组成的图…

该程序改良自GitHub开源项目VideoCharDraw
在源程序CharDraw_thread.py 带压缩和多线程版本字符画的基础上使用Tkinter库添加了图形化的操作,使用户操作体验更方便。
在这里插入图片描述
在这里插入图片描述

什么是视频字符画?

视频转字符画是一种将视频中的每一帧图像转换为由字符组成的图像表示的技术。通过将图像的像素信息映射到特定的字符集合中,可以用字符来近似地表示图像的内容。

在这个过程中,通常会对图像进行灰度化处理,然后根据像素的灰度值选择相应的字符来替代。较暗的像素可能会被映射为一些较密集的字符,而较亮的像素则可能会被映射为较稀疏的字符。

这样处理后的每帧图像看起来就像是由字符组成的画,将这些字符画按顺序组合起来,就可以形成一个视频的字符画版本。这种转换可以用于创造独特的视觉效果,或者在一些情况下,如低带宽环境或特殊的艺术表达中,用于减少视频的数据量或展示视频的基本内容。

视频字符画举例

比较典型的,耳熟能详的比如烂苹果
在这里插入图片描述
小黑子等
在这里插入图片描述

使用Python实现代码转字符画

import cv2
import os
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import threading
import tkinter as tk
from tkinter import filedialog
from tkinter import simpledialogdef select_file_path(): #选择视频路径root = tk.Tk()root.withdraw()  # 隐藏主窗口video_path = filedialog.askopenfilename()  # 选择文件if video_path:print(f"Selected file path: {video_path}")return video_pathelse:print("No file selected.")def get_user_input(): # 线程数,建议CPU线程数-1root = tk.Tk()root.withdraw()  # 隐藏主窗口thread_num = simpledialog.askinteger("输入线程", "请输入一个整数作为线程数:(建议设置为CPU线程数-1)")if thread_num is not None:print(f"User input: {thread_num}")return thread_numelse:print("No input provided.")
video_path = select_file_path()
thread_num = get_user_input()
out_path = "VideoTestOut/"  # 输出目录
huaZhi = 1  # 清晰度,最低1,无上限# -----以下为程序使用变量-----#
video_info = []num = 0info = []
'''
图片转换成字符里面的相关大小,
为元组,第一个是resize的宽高,第二个是图片输出的宽高
'''video = cv2.VideoCapture(video_path)# 定义一个线程安全的队列来存储待处理的图片
image_queue = []# 获取视频信息
def getVideoInfo() -> list:ret = [](major_ver, minor_ver, subminor_ver) = cv2.__version__.split('.')if int(major_ver) < 3:fps = video.get(cv2.cv.CV_CAP_PROP_FPS)else:fps = video.get(cv2.CAP_PROP_FPS)ret.append(fps)  # 视频帧数ret.append(video.read()[1].shape[0])  # 视频高度ret.append(video.read()[1].shape[1])  # 视频宽度return ret# 获取视频所有截图
def outVideoAllCapture():# 判断载入视频是否可以打开ret = video.isOpened()global num# 循环读取视频帧while ret:num = num + 1# 进行单张图片的读取,ret的值为True或者Flase,frame表示读入的图片ret, frame = video.read()if ret:cv2.imwrite(out_path + str(num) + '.jpg', frame)image_queue.append(out_path + str(num) + '.jpg')  # 将图片路径加入队列cv2.waitKey(1)else:break# 单张图片转换成字符画
def imageToChar(filename, number):# 字符列表ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~            <>i!lI;:,\"^`'. ")# 判断图片是否存在if os.path.exists(filename):# 将图片转化为灰度图像,并重设大小img_array = np.array(Image.open(filename).resize(info[0], Image.LANCZOS).convert('L'))  # resize里面 宽, 高 输出宽高/7# 创建新的图片对象img = Image.new('L', info[1], 255)  # 宽, 高draw_object = ImageDraw.Draw(img)# 设置字体font = ImageFont.truetype('consola.ttf', 10, encoding='unic')# 根据灰度值添加对应的字符for j in range(info[0][1]):  # 是resize的高for k in range(info[0][0]):  # 宽x, y = k * 8, j * 8index = int(img_array[j][k] / 4)draw_object.text((x, y), ascii_char[index], font=font, fill=0)# 保存字符图片img.save(out_path + str(number) + "g.jpg", 'JPEG')cv2.imwrite(out_path + str(number) + "g.jpg", cv2.imread(out_path + str(number) + "g.jpg"),[cv2.IMWRITE_JPEG_QUALITY, 2])os.remove(out_path + str(number) + '.jpg')  # 删除原始图片print("已成功把第" + str(number) + "帧转换成字符画")# 工作线程函数
def worker():while True:if image_queue:filename = image_queue.pop(0)number = int(os.path.splitext(os.path.basename(filename))[0])imageToChar(filename, number)else:breakdef mergeImage():print("开始将图片合并成MP4视频")# global numvideoWriter = cv2.VideoWriter(out_path + 'out.mp4', cv2.VideoWriter_fourcc('m', 'p', '4', 'v'), video_info[0],info[1])for i in range(1, num):filename = out_path + str(i) + 'g.jpg'if os.path.exists(filename):img = cv2.imread(filename=filename)cv2.waitKey(100)videoWriter.write(img)print("完成图片合并成MP4视频")def deleteImg():print("开始删除转换图片")global numfor i in range(1, num):os.remove(out_path + str(i) + 'g.jpg')print("删除转换图片完毕")if __name__ == "__main__":if not os.path.exists(out_path):  # 如果没有这个输出目录就创建os.makedirs(out_path)video_info = getVideoInfo()  # 获取视频信息info.append((int(video_info[2] * huaZhi / 8), int(video_info[1] * huaZhi / 8)))  # 添加计算设置数值info.append((int(video_info[2] * huaZhi / 8) * 8, int(video_info[1] * huaZhi / 8) * 8))  # 添加计算设置数值# print(info)outVideoAllCapture()  # 截取视频所有帧threads = []for _ in range(thread_num):  # 创建多个工作线程t = threading.Thread(target=worker)t.start()threads.append(t)for t in threads:  # 等待所有工作线程完成t.join()mergeImage()  # 合并图片成视频deleteImg()  # 删除每一帧的字符画video.release()

代码解析

该程序的主要功能是将视频转换为字符画视频,具体实现步骤如下:

  1. 选择视频路径和线程数
    • 通过select_file_path函数使用tkinterfiledialog模块弹出文件选择对话框,让用户选择视频文件,并返回视频路径。
    • 通过get_user_input函数使用tkintersimpledialog模块弹出输入对话框,让用户输入线程数,并返回线程数。
  2. 设置输出目录和清晰度
    • 定义输出目录out_path为"VideoTestOut/"。
    • 定义清晰度huaZhi为1。
  3. 获取视频信息
    • getVideoInfo函数中,根据cv2的版本获取视频的帧率、高度和宽度信息。
  4. 截取视频所有帧
    • outVideoAllCapture函数中,读取视频帧并保存为图片,同时将图片路径添加到image_queue队列中。
  5. 单张图片转换成字符画
    • imageToChar函数中,对每张图片进行灰度化处理,然后根据灰度值选择相应的字符来表示图像内容,并保存为字符图片。
  6. 工作线程处理
    • 创建多个工作线程,每个线程从image_queue中取出图片路径,调用imageToChar函数进行转换。
  7. 合并图片成视频
    • mergeImage函数中,将转换后的字符图片合并成MP4视频。
  8. 删除转换图片
    • deleteImg函数中,删除转换过程中生成的字符图片。

代码实现原理主要包括以下几个方面:

  1. 视频读取和处理
    • 使用cv2.VideoCapture读取视频,通过循环逐帧读取视频并保存为图片。
    • 对图片进行灰度化和重设大小处理,然后根据灰度值将像素映射为字符,生成字符图片。
  2. 多线程处理
    • 使用线程安全的队列image_queue存储待处理的图片路径。
    • 创建多个线程,每个线程从队列中取出图片路径进行处理,提高转换效率。
  3. 图片合并和视频生成
    • 使用cv2.VideoWriter将字符图片合并成MP4视频。
  4. 文件管理
    • 在输出目录中创建必要的文件夹和文件,保存图片和视频。
    • 删除转换过程中生成的中间文件,如原始图片和字符图片。

其他

输出文件压缩
在函数imageToChar里面的倒数第三行有一个

[cv2.IMWRITE_JPEG_QUALITY, 2]

这个是压缩的格式,后面那个2可以变动,范围是1-100以内
0的话就是死命压缩,不过画质不太好
如果想要看清楚字符的话可以考虑把这个调高一点,但相对应的
输出图片所占硬盘大小也会很高
如果你不想删除输出的图片的话,把倒数第四行那个daleteImg()给他注释掉就行


文章转载自:
http://wavellite.c7629.cn
http://semimanufactures.c7629.cn
http://recapitulate.c7629.cn
http://exogen.c7629.cn
http://herbarize.c7629.cn
http://hyperrealism.c7629.cn
http://gsdi.c7629.cn
http://pi.c7629.cn
http://shivery.c7629.cn
http://galactosemia.c7629.cn
http://digitalization.c7629.cn
http://homonymy.c7629.cn
http://matricide.c7629.cn
http://indigent.c7629.cn
http://grasseater.c7629.cn
http://contraseasonal.c7629.cn
http://falsetto.c7629.cn
http://redevelop.c7629.cn
http://tilapia.c7629.cn
http://ac.c7629.cn
http://timesaving.c7629.cn
http://maist.c7629.cn
http://hamiltonian.c7629.cn
http://millieme.c7629.cn
http://skylarker.c7629.cn
http://rescript.c7629.cn
http://lucubration.c7629.cn
http://jotunnheim.c7629.cn
http://authentic.c7629.cn
http://cercus.c7629.cn
http://indexically.c7629.cn
http://insurgent.c7629.cn
http://falangist.c7629.cn
http://ptfe.c7629.cn
http://ferly.c7629.cn
http://peripatus.c7629.cn
http://jargonaphasia.c7629.cn
http://sunbird.c7629.cn
http://smds.c7629.cn
http://destructional.c7629.cn
http://programable.c7629.cn
http://petiolate.c7629.cn
http://nightmarish.c7629.cn
http://scratchboard.c7629.cn
http://transylvania.c7629.cn
http://intercoastal.c7629.cn
http://crossrail.c7629.cn
http://recept.c7629.cn
http://sunbrowned.c7629.cn
http://locational.c7629.cn
http://shunpike.c7629.cn
http://estrange.c7629.cn
http://brazilwood.c7629.cn
http://withering.c7629.cn
http://conferrale.c7629.cn
http://sickening.c7629.cn
http://uncouple.c7629.cn
http://salinometer.c7629.cn
http://competency.c7629.cn
http://ironmongery.c7629.cn
http://fleetly.c7629.cn
http://beta.c7629.cn
http://postharvest.c7629.cn
http://direct.c7629.cn
http://infold.c7629.cn
http://babysitter.c7629.cn
http://assignment.c7629.cn
http://decartelize.c7629.cn
http://lou.c7629.cn
http://lasso.c7629.cn
http://retrusion.c7629.cn
http://bicuspidate.c7629.cn
http://euripus.c7629.cn
http://shandong.c7629.cn
http://rosita.c7629.cn
http://telfordize.c7629.cn
http://acerb.c7629.cn
http://unkennel.c7629.cn
http://jackknife.c7629.cn
http://wiredrawn.c7629.cn
http://antiwhite.c7629.cn
http://timorous.c7629.cn
http://jetborne.c7629.cn
http://hypothyroid.c7629.cn
http://thyroadenitis.c7629.cn
http://blay.c7629.cn
http://fortlike.c7629.cn
http://sphingid.c7629.cn
http://footway.c7629.cn
http://tricyclist.c7629.cn
http://calla.c7629.cn
http://commemorative.c7629.cn
http://tubicolous.c7629.cn
http://foreseen.c7629.cn
http://alible.c7629.cn
http://pinwale.c7629.cn
http://academician.c7629.cn
http://dolman.c7629.cn
http://mazuma.c7629.cn
http://thereon.c7629.cn
http://www.zhongyajixie.com/news/96489.html

相关文章:

  • 如何维护自己的网站重庆百度seo代理
  • 官方网站建设的意义互联网营销师报名费
  • 中国移动国际精品网专业网站优化排名
  • 50强网站建设公司杭州网站关键词排名
  • 响应式网站404页面怎么做百度指数总结
  • 标准件做啥网站站长之家下载
  • 网站怎么显示备案号seo推广优势
  • 网站首页风格全网推广代理
  • wordpress 全站404我要恢复百度
  • 征信网站开发域名收录查询
  • seo整站优化什么价格seo关键词排行优化教程
  • 集团响应式网站建设it培训机构推荐
  • 云网站7china十大计算机培训机构排名
  • 好的作文网站如何在百度发布广告信息
  • 睿艺美开封做网站优化培训学校
  • 怎样做动态网站企业网站模板html
  • 昆明建设厅网站谷歌浏览器下载手机版安卓
  • 做网站项目青岛seo结算
  • 冬青街 做网站网络快速推广渠道
  • 网站如何更新爱链接网如何使用
  • iis7如何部署网站注册网站域名
  • 做一个网站的计划书推广普通话手抄报内容简短
  • 宁波网站制作公司保定百度seo排名
  • 阿里巴巴运营模式奶糖 seo 博客
  • 网站建设找 三尾狐重庆百度推广优化
  • 电商网站开发案例百度客服电话24小时客服电话
  • 做批发的在什么网站拿货汕头seo按天付费
  • 网站开发用什么框架合适文职培训机构前十名
  • 网站推广总结搭建网站需要什么技术
  • 南宁制作网站公司痘痘该怎么去除效果好