用python流水线式下载B站视频,提取每一帧图片并去重,制作成PDF文档

工站一、下载视频方式

本想用爬虫进行系列视频爬取的,但是发现了一款专门用来下载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

扫描二维码关注公众号,回复: 15943911 查看本文章

这种方式合成方法会把整张图片铺满一页,像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)

猜你喜欢

转载自blog.csdn.net/quantam/article/details/119253175