Como criar miniaturas para vídeos com python e opencv





Às vezes, separando os escombros de arquivos de vídeo grandes e pequenos em uma pasta (pastas), não há tempo para examinar o conteúdo de cada arquivo. É aqui que vêm à mente as chamadas miniaturas, que permitem criar uma ideia do conteúdo na forma de recortar fragmentos de um vídeo.



Vamos criar um pequeno programa que irá criar miniaturas para cada um dos arquivos na pasta do Windows atual e adicionar uma linha do tempo aos arquivos cortados.



Importação padrão de módulos no início de um programa Python:



import numpy as np
import cv2
import os


Indicamos em qual pasta procurar os arquivos e adicionamos uma mensagem ao usuário:



file=file
print('...')
path=r'E:\1'
os.chdir(path)


Aqui, o programa processa todos os arquivos no drive E na pasta 1.



Em seguida, opencv entra na batalha, corta os quadros e a linha do tempo para eles:



vidcap = cv2.VideoCapture(path+'\\'+file)
    fps = vidcap.get(cv2.CAP_PROP_FPS)
    #print(fps)
    n=12
    total_frames = vidcap.get(cv2.CAP_PROP_FRAME_COUNT)
    time_line = total_frames / fps

    frames_step = total_frames//n
    time_line_step=time_line//n
    #print(int(time_line_step))
    a=[]
    b=[]


n - a quantidade de limas no fatiamento, 12 peças.



Como a divisão da linha do tempo é em segundos, para que seja exibida corretamente nos frames, vamos

adicionar uma função que leva ao formato de hora 00:00:00:



def sec_to_time(t):
        h=str(t//3600)
        m=(t//60)%60
        s=t%60
        if m<10:
            m='0'+str(m)
        else:
            m=str(m)
        if s<10:
            s='0'+str(s)
        else:
            s=str(s)    
        #print(h+':'+m+':'+s)
        t=h+':'+m+':'+s
        return t


Agora obtemos as imagens, reduzimos seu tamanho em 50% e salvamos no disco como arquivos intermediários:



for i in range(n):        
        vidcap.set(1,i*frames_step)
        success,image = vidcap.read()
        #  
        scale_percent = 50
        width = int(image.shape[1] * scale_percent / 100)
        height = int(image.shape[0] * scale_percent / 100)
        image=cv2.resize(image, (width, height))

        #     c time_line
        font = cv2.FONT_HERSHEY_COMPLEX    
        t=int(time_line_step)*i    
        image=cv2.putText(image, sec_to_time(t), (100, 30), font, 0.5, color=(0, 0, 255), thickness=0)   
        cv2.imwrite('image'+str(i)+'.jpg',image)
        a.append('image'+str(i)+'.jpg')
    vidcap.release()


Colamos os arquivos resultantes, usando opencv, horizontalmente entre si, observando a ordem:



def glue (img1,img2,img3,x):
        i1 = cv2.imread(img1)
        i2 = cv2.imread(img2)
        i3 = cv2.imread(img3)    
        vis = np.concatenate((i1, i2, i3), axis=1)
        cv2.imwrite('out'+str(x)+'.png', vis)
        b.append('out'+str(x)+'.png')
    x=0
    while x<len(a):    
        glue(a[x],a[x+1],a[x+2],x)
        x+=3


Cole os "trigêmeos" resultantes verticalmente:



 #   
    def glue2 (img1,img2,img3,img4):
        i1 = cv2.imread(img1)
        i2 = cv2.imread(img2)
        i3 = cv2.imread(img3)
        i4 = cv2.imread(img4) 
        vis = np.concatenate((i1, i2, i3,i4), axis=0)
        cv2.imwrite(file[:-4]+'.jpeg', vis)
    glue2(b[0],b[1],b[2],b[3])


Limpamos a pasta excluindo arquivos temporários:



#
    c=['jpg', 'png']
    for root, dirs, files in os.walk(path):    
        for file in files:
            if file[-3:] in c:
                os.remove(file)


Realizamos os procedimentos acima para todos os arquivos de vídeo na pasta:



video=['wmv', 'mp4', 'avi', 'mov', 'MP4', '.rm', 'mkv']
for root, dirs, files in os.walk(r'E:/1'):    
    for file in files:
        if file[-3:] in video:
            print(' -'+file)
            tumbnail(file)


O código do programa para aqueles a quem pertenço, primeiro baixa o código e depois lê o artigo - download .



A linha do tempo do PS tem pecado e está um pouco fora de sintonia com o vídeo da linha do tempo real.



Isso é especialmente perceptível em arquivos de vídeo grandes.



All Articles