工站一、下载视频方式
本想用爬虫进行系列视频爬取的,但是发现了一款专门用来下载B站视频的软件----唧唧–B站下载神器(绿色版),直接把下载地址贴上去就可以下载了,还自动带出整个系列视频的链接,简直不要太懒。
本视频以下载“信息系统项目管理师”为例,下载后的视频保存成MP4格式。
工站二、从视频中拆分出每一帧
由于视频的帧率为25帧/秒或者是30帧/秒,用这句**cap.get(cv2.CAP_PROP_FPS)**查看,没有必要所有的都保留,跳帧保存就好,我每隔30帧保存一张,并进行命名,这个排序对后面制作PDF有用。
使用方式2的系列视频自动拆分,把程序跑起来后就可以喝喝水,玩玩手机了。
但是。。。
常规的视频每一帧的像素大小为1920*1080,但是有时候会比这个小,程序报错,所以要写一个单个视频拆分的程序。
方式1、单个视频拆分
#单个视频拆分
import cv2
import os
path=r'E:\Bli\信息系统项目管理师视频\13.13项目进度管理1(Av57544874,P13).mp4' #
data_path='E:/Bli/P13/'
if os.path.exists(data_path):
pass
else:
os.mkdir(data_path)
cap = cv2.VideoCapture(path)
cap.get(cv2.CAP_PROP_FPS)
cap.get(cv2.CAP_PROP_FRAME_COUNT)
frame_count = 1
success = True
while(success):
success, frame = cap.read()
if frame_count%30==0:
cv2.imwrite(data_path + "%d.png" %int(frame_count/30), frame)
frame_count = frame_count + 1
方式2、系列视频自动拆分
#系列视频拆分
import cv2
import os
path='E:/Bli/信息系统项目管理师视频/P13'
for file in os.listdir(path):
d_path=path+file
p=file.split(',')[1].split(')')[0]
data_path='E:/Bli/%s'%p+'/'
if os.path.exists(data_path):
pass
else:
os.mkdir(data_path)
cap = cv2.VideoCapture(d_path)
fps=cap.get(cv2.CAP_PROP_FRAME_COUNT)
frame_count = 1
success = True
while(success):
success, frame = cap.read()
if frame_count%30==0:
cv2.imwrite(data_path + "%d.png" %int(frame_count/30), frame)
frame_count = frame_count + 1
if frame_count>=fps:
break
工站三、图片去重
由于拆分出来的视频有很多重复的,比如老师在讲解知识点时会进行写写画画,这时候我只保留第一张,后面的都不要。
图片去重思路:
1、读取第一张命名为A和第二张命名为B,A和B进行比对,当他们的相似度大于阈值时,移第二张到其他文件夹,也可以删除,移走的好处是后期检验时可以恢复。
2、读取第三张和第一张对比,当相似度大于阈值时,移走B,B+1,否则把B给A,B+1,继续比对,直到处理完所有图像。
import os
import shutil
import cv2
from skimage.metrics import structural_similarity as ssim
path = 'E:/Bli/XMGL/'
files=os.listdir(path)
for i in range(1,35):
file=files[i]
# file='P30'
print(file)
backup='E:/Bli/backup/'+file+'/'
if os.path.exists(backup):
pass
else:
os.mkdir(backup)
start1=1
start2=2
L=len(os.listdir(path+file))
while start2<=L :
path1=path+file+'/'+str(start1)+'.png'
if os.path.exists(path1):
img1=cv2.imread(path1)
img1_size=img1.shape[0]
else:
start1=start1+1
while os.path.exists(path1):
path2=path+file+'/'+str(start2)+'.png'
if os.path.exists(path2):
img2=cv2.imread(path2)
img2_size=img2.shape[0]
if img1_size!=img2_size:
start1=start2
start2=start2+1
break
else:
pass
ssim_value = ssim(img1,img2,multichannel=True)
if ssim_value>0.9:
if os.path.exists(backup+str(start2)+'.png'):
pass
else:
shutil.move(path2,backup)
start2=start2+1
else:
start1=start2
start2=start2+1
break
else:
start2=start2+1
if start2>L:
break
工站四、图片合成PDF文件
方式1
这种方式合成方法会把整张图片铺满一页,像PPT一页,推荐使用这种办法。
#以此份为准
from PIL import Image
import os
def combine2Pdf( folderPath, pdfFilePath ):
files = os.listdir( folderPath )
P=[]
for file in files:
P.append(int(file.split('.')[0]))
P=sorted(P)
pngFiles = [os.path.join(folderPath,str(i)+'.png') for i in P]
output = Image.open( pngFiles[0] )
pngFiles.pop( 0 )
sources = []
for file in pngFiles:
pngFile = Image.open( file )
if pngFile.mode == "RGB":
pngFile = pngFile.convert( "RGB" )
sources.append( pngFile )
output.save( pdfFilePath, "pdf", save_all=True, append_images=sources )
if __name__ == "__main__":
for i in range(1,35):
folder = r"E:\Bli\XMGL\P%s\\"%i
pdfFile = r"E:\Bli\P%s.pdf"%i
combine2Pdf( folder, pdfFile )
方式2
这种办法生成的PDF效果不是很好,图片只是占一页A4的中间,前后剩余很多空白。
import img2pdf
import os
save_path= 'E:\\Bli\\result\\P%s'
for i in range(1,35):
photo_path = r'E:\Bli\XMGL\P'+str(i)
photo_list = os.listdir(photo_path)
P=[]
for pho in photo_list:
P.append(int(pho.split('.')[0]))
P=sorted(P)
photo = [os.path.join(photo_path,str(i)+'.png') for i in P]
# 指定pdf的单页的宽和高
# A4纸张
a4inpt = (img2pdf.mm_to_pt(210), img2pdf.mm_to_pt(297))
# 我的自定义:
# a4inpt = (img2pdf.mm_to_pt(720), img2pdf.mm_to_pt(1080))
layout_fun = img2pdf.get_layout_fun(a4inpt)
with open('E:\\Bli\\result\\P%s.pdf'%str(i), 'wb') as f:
f.write(img2pdf.convert(photo, layout_fun=layout_fun))
至此,已完成所有的工作,另外,如果我们要从图片中提取文字,有下一节
工站五、图片文字识别
from PIL import Image
import pytesseract
text=pytesseract.image_to_string(Image.open(r'E:\Bli\backup\P14\2.png'),lang='chi_sim')
print(text)