最后
🍅 硬核资料:关注即可领取PPT模板、简历模板、行业经典书籍PDF。
🍅 技术互助:技术群大佬指点迷津,你的问题可能不是问题,求资源在群里喊一声。
🍅 面试题库:由技术群里的小伙伴们共同投稿,热乎的大厂面试真题,持续更新中。
🍅 知识体系:含编程语言、算法、大数据生态圈组件(Mysql、Hive、Spark、Flink)、数据仓库、Python、前端等等。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
第一步视频拆分成视频
首先使用cv2.VideoCapture进行视频进行抽帧,将抽帧好的图片使用read方式进行读取,把读取好的数据保存在文件夹里,使用数字来保存图片名,也方便我们在之后进行提取图片数据进行使用
# 将视频转换为图片 并进行计数,返回总共生成了多少张图片!
def video\_to\_pic(vp):
# vp = cv2.VideoCapture(video\_path)
number = 0
if vp.isOpened():
r, frame = vp.read()
if not os.path.exists('cache\_pic'):
os.mkdir('cache\_pic')
os.chdir('cache\_pic')
else:
r = False
while r:
number += 1
cv2.imwrite(str(number) + '.jpg', frame)
r, frame = vp.read()
print('\n由视频一共生成了{}张图片!'.format(number))
os.chdir("..")
return number
将图片转换字符画
循环取出文件夹里面所有的图片数据进行转换,首先通过cv2进行图片读取,获取到他的图片数据通道,获取到图片数据的3通道rgb的数据信息,在将数据进行灰度处理,我们需要用他的颜色用来区分他的数据样式,所以只能灰度来实现,在使用numpy进行数据转换,将获取到的矩阵数据进行降维,转换成一个类似列表的数据信息,使用kmeans算法对图像数据进行分类,设置他的矩阵中心数,最大迭代数,以及试错等级,k聚类算法可以自行了解,会给我们返回labels(类别)、centroids(矩心) compactness(密度值),将矩心进行数据转换成整数,我们可以更好的替换符号,对矩心进行排序,矩心大的说明颜色越暗,矩心小的越淡,在根据亮度数据将数据进行替换成一个新的画布,将我们的符号替换到画布上去,到这里我们就能吧单独的图片替换成字符画了
def img2strimg(frame, K=3):
# 读取矩阵的长度 有时返回两个值,有时三个值
height, width, \*_ = frame.shape
# print(frame.shape)
# 颜色空间转化 图片对象, 灰度处理
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# print(frame\_gray)
# 转换数据类型,将数据降维
frame_array = np.float32(frame_gray.reshape(-1))
# print(frame\_array)
# 得到labels(类别)、centroids(矩心) compactness(密度值)。
# 如第一行6个像素labels=[0,2,2,1,2,0],则意味着6个像素分别对应着 第1个矩心、第3个矩心、第3、2、3、1个矩心。
compactness, labels, centroids = cv2.kmeans(frame_array, K, None, (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0), 10, cv2.KMEANS_RANDOM_CENTERS)
print(labels)
centroids = np.uint8(centroids) # 转换成整形
# labels的数个矩心以随机顺序排列,所以需要简单处理矩心.
# 返回一个折叠成一维的数组
centroids = centroids.flatten()
# 排序
centroids_sorted = sorted(centroids)
# 获得不同centroids的明暗程度,0最暗
centroids_index = np.array([centroids_sorted.index(value) for value in centroids])
# 亮度设置
bright = [abs((3 \* i - 2 \* K) / (3 \* K)) for i in range(1, 1 + K)]
bright_bound = bright.index(np.min(bright))
# 背景阴影设置
shadow = [abs((3 \* i - K) / (3 \* K)) for i in range(1, 1 + K)]
shadow_bound = shadow.index(np.min(shadow))
# 返回一个折叠成一维的数组
labels = labels.flatten()
print(labels)
# 将labels转变为实际的明暗程度列表,0最暗。
labels = centroids_index[labels]
print(labels)
# 列表解析,每2\*2个像素挑选出一个,组成(height\*width\*灰)数组。
labels_picked = [labels[rows \* width:(rows + 1) \* width:2] for rows in range(0, height, 2)]
canvas = np.zeros((3 \* height, 3 \* width, 3), np.uint8)
canvas.fill(255) # 创建长宽为原图三倍的白色画布。
# 因为 字体大小为0.45时,每个数字占6\*6个像素,而白底画布为原图三倍
# 所以 需要原图中每2\*2个像素中挑取一个,在白底画布中由6\*6像素大小的数字表示这个像素信息。
y = 0
for rows in labels_picked:
x = 0
for cols in rows:
if cols <= shadow_bound:
# 添加文字 图片,添加的文字,左上角坐标,字体,字体大小,颜色,字体粗细
cv2.putText(canvas, str(random.randint(2, 9)), (x, y), cv2.FONT_HERSHEY_PLAIN, 0.45, 0.1)
elif cols <= bright_bound:
cv2.putText(canvas, "-", (x, y),cv2.FONT_HERSHEY_PLAIN, 0.4, 0, 1)
x += 6
y += 6
return canvas
合成视频
将全部的图片数据在进行合成一个新的视频,视频数据尽量不要太大,帧数越细的话,生成的视频越大,可能好几个G
def jpg\_to\_video(char_image_path, FPS):
video_fourcc = cv2.VideoWriter_fourcc(\*"MP42") # 设置视频编码器,这里使用使用MP42编码器,可以生成更小的视频文件
char_img_path_list = [char_image_path + r'/{}.jpg'.format(i) for i in range(1, number + 1)] # 生成目标字符图片文件的路径列表
char_img_test = Image.open(char_img_path_list[1]).size # 获取图片的分辨率
if not os.path.exists('video'):
os.mkdir('video')
video_writter = cv2.VideoWriter('video/new\_char\_video.avi', video_fourcc, FPS, char_img_test)
sum = len(char_img_path_list)
count = 0
for image_path in char_img_path_list:
img = cv2.imread(image_path)
video_writter.write(img)
end_str = '100%'
count = count + 1
process_bar(count / sum, start_str='', end_str=end_str, total_length=15)
video_writter.release()
print('\n')
print('=======================')
print('The video is finished!')
print('=======================')
简易源码分享
# from platypus import
import os
from PIL import Image, ImageFont, ImageDraw
import cv2
import random
import numpy as np
import threading
# 将视频转换为图片 并进行计数,返回总共生成了多少张图片!
def video\_to\_pic(vp):
# vp = cv2.VideoCapture(video\_path)
number = 0
if vp.isOpened():
r, frame = vp.read()
if not os.path.exists('cache\_pic'):
os.mkdir('cache\_pic')
os.chdir('cache\_pic')
else:
r = False
while r:
number += 1
cv2.imwrite(str(number) + '.jpg', frame)
r, frame = vp.read()
print('\n由视频一共生成了{}张图片!'.format(number))
os.chdir("..")
return number
def star\_to\_char(number, save_pic_path):
if not os.path.exists('cache\_char'):
os.mkdir('cache\_char')
img_path_list = [save_pic_path + r'/{}.jpg'.format(i) for i in range(1, number + 1)] # 生成目标图片文件的路径列表
task = 0
for image_path in img_path_list:
img_width, img_height = Image.open(image_path).size # 获取图片的分辨率
task += 1
# img\_to\_char(image\_path, img\_width, img\_height, task)
print('{}/{} is finished.'.format(task, number))
print('=======================')
print('All image was finished!')
print('=======================')
return 0
def img2strimg(frame, K=3):
# 读取矩阵的长度 有时返回两个值,有时三个值
height, width, \*_ = frame.shape
# print(frame.shape)
# 颜色空间转化 图片对象, 灰度处理
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# print(frame\_gray)
# 转换数据类型,将数据降维
frame_array = np.float32(frame_gray.reshape(-1))
# print(frame\_array)
# 得到labels(类别)、centroids(矩心) compactness(密度值)。
# 如第一行6个像素labels=[0,2,2,1,2,0],则意味着6个像素分别对应着 第1个矩心、第3个矩心、第3、2、3、1个矩心。
compactness, labels, centroids = cv2.kmeans(frame_array, K, None, (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0), 10, cv2.KMEANS_RANDOM_CENTERS)
print(labels)
centroids = np.uint8(centroids) # 转换成整形
# labels的数个矩心以随机顺序排列,所以需要简单处理矩心.
# 返回一个折叠成一维的数组
centroids = centroids.flatten()
# 排序
centroids_sorted = sorted(centroids)
# 获得不同centroids的明暗程度,0最暗
centroids_index = np.array([centroids_sorted.index(value) for value in centroids])
# 亮度设置
bright = [abs((3 \* i - 2 \* K) / (3 \* K)) for i in range(1, 1 + K)]
bright_bound = bright.index(np.min(bright))
# 背景阴影设置
shadow = [abs((3 \* i - K) / (3 \* K)) for i in range(1, 1 + K)]
shadow_bound = shadow.index(np.min(shadow))
# 返回一个折叠成一维的数组
labels = labels.flatten()
print(labels)
# 将labels转变为实际的明暗程度列表,0最暗。
labels = centroids_index[labels]
print(labels)
# 列表解析,每2\*2个像素挑选出一个,组成(height\*width\*灰)数组。
labels_picked = [labels[rows \* width:(rows + 1) \* width:2] for rows in range(0, height, 2)]
canvas = np.zeros((3 \* height, 3 \* width, 3), np.uint8)
canvas.fill(255) # 创建长宽为原图三倍的白色画布。
# 因为 字体大小为0.45时,每个数字占6\*6个像素,而白底画布为原图三倍
# 所以 需要原图中每2\*2个像素中挑取一个,在白底画布中由6\*6像素大小的数字表示这个像素信息。
y = 0
for rows in labels_picked:
x = 0
for cols in rows:
if cols <= shadow_bound:
# 添加文字 图片,添加的文字,左上角坐标,字体,字体大小,颜色,字体粗细
cv2.putText(canvas, str(random.randint(2, 9)), (x, y), cv2.FONT_HERSHEY_PLAIN, 0.45, 0.1)
elif cols <= bright_bound:
cv2.putText(canvas, "-", (x, y),cv2.FONT_HERSHEY_PLAIN, 0.4, 0, 1)
x += 6
y += 6
return canvas
def jpg\_to\_video(char_image_path, FPS):
video_fourcc = cv2.VideoWriter_fourcc(\*"MP42") # 设置视频编码器,这里使用使用MP42编码器,可以生成更小的视频文件
char_img_path_list = [char_image_path + r'/{}.jpg'.format(i) for i in range(1, number + 1)] # 生成目标字符图片文件的路径列表
char_img_test = Image.open(char_img_path_list[1]).size # 获取图片的分辨率
现在能在网上找到很多很多的学习资源,有免费的也有收费的,当我拿到1套比较全的学习资源之前,我并没着急去看第1节,我而是去审视这套资源是否值得学习,有时候也会去问一些学长的意见,如果可以之后,我会对这套学习资源做1个学习计划,我的学习计划主要包括规划图和学习进度表。
分享给大家这份我薅到的免费视频资料,质量还不错,大家可以跟着学习
![](https://img-blog.csdnimg.cn/img_convert/21b2604bd33c4b6713f686ddd3fe5aff.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618317507)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**