Русский
Русский
English
Статистика
Реклама

Timeline

Создаем thumbnails для видео с python и opencv

26.08.2020 16:11:24 | Автор: admin


Порой, разбирая завалы больших и малых видеофайлов в папке(папках) нет времени заглядывать в содержимое каждого файла. Тут на ум приходят так называемые thumbnails, которые позволяют в виде нарезки фрагментов из видео, создать представление о содержимом.

Создадим небольшую программу, которая создаст thumbnails для каждого из файлов в текущей папке windows, и добавит timeline к вырезанным файлам.

Стандартный импорт модулей в начале программы на python:

import numpy as npimport cv2import os

Укажем, в какай папке искать файлы и добавим сообщение для пользователя:

file=fileprint('Подождите...')path=r'E:\1'os.chdir(path)

Здесь программа обрабатывает все файлы на диске E в папке 1.

Далее вступает в бой opencv, нарезает кадры и timeline к ним:

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 количество файлов в нарезке, 12 штук.

Так как нарезка timeline в секундах, чтобы она корректно отображалась на кадрах,
добавим функцию, приводящую к формату времени 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

Теперь получаем картинки, уменьшаем их размер на 50% и сохраняем их на диск, как промежуточные файлы:

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()

Склеиваем полученные файлы, используя opencv, между собой по горизонтали, соблюдая очередность:

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

Получившиеся тройки склеиваем по вертикали:

 #склеиваем видео по вертикали    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])

Прибираемся в папке, удаляя временные файлы:

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

Проводим вышеуказанные процедуры для всех видеофайлов в папке:

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)

Код программы для тех, к коим отношусь и я, сначала скачивает код, а потом читает статью скачать.

P.S. timeline не без греха и немного отрывается от реальной timeline видео.

Особенно это заметно на больших видеофайлах.
Подробнее..

Recovery mode O tempora, o mores!

05.09.2020 10:09:13 | Автор: admin

Для протокола: заголовок я позаимствовал у Цицерона, в Oratio in Catilinam Prima in Senatu Habita.


Cicero Denounces Catiline, fresco by Cesare Maccari, 18821888




В реальной жизни мы часто имеем дело с временными интервалами. Свиданки с зубным врачом, бронирование гостиничных номеров, даже ежедневный обеденный перерыв: планирование всего этогозадача подгонки временного интервала в ряд других временных интервалов.


Допустим, нам пора навестить стоматолога. Я знаю, что мне нужен 1 час для ежегодной плановой проверки. Я могу посетить врача во время обеда или после работы. У доктора есть и другие пациенты. На диаграмме ниже мои рабочие часы показаны фиолетовым цветом, докторскиекрасным, нерабочиесерым, а счастливо найденный слот, когда мы оба свободны, зеленым.


Timelines of my busy hours and the dentists busy hours


Беглого взгляда на эту диаграмму достаточно, чтобы определить время назначенной встречи. Завтра, в обеденное время. Легко, да?


К сожалению, ни один из известных мне языков программирования не предоставляет возможности определить это программно. Последние несколько лет я состою в тесных отношениях с эликсиром, поэтому пришлось написать библиотеку, решающую именно эту проблему.


Итак, встречайте Tempus!


Детали реализации


Сущность, вокруг которой построена вся библиотека Slot. Он представляет временной интервал самым естественным и простым способом: это структура, с полями from и to, оба типа DateTime. Набор слотов хранится в структуре Slots, под капотом реализованной как AVLTree. Этот выбор был сделан для того, чтобы сохранить базовый список слотов согласованным (упорядоченным и не перекрывающимся) с наименьшими затратами при оптимизации доступа по чтению и записи. Обычно список слотов заполняется при инициализации и потом используется для проверки, поиска свободных интервалов, и тому подобного.


Функция Slots.add/2 добавит в список слотовновый, объединяя слоты по мере необходимости. Это позволяет просто вставлять новые слоты в конструкцию, не беспокоясь о порядке и перекрытии. Также предусмотрена вспомогательная функция Slots.merge/2 для объединения двух наборов слотов. Последнее особенно удобно, когда нужно, например, найти пустой слот в обеих сериях, как в примере с выбором времени посещения дантиста выше.


Можно также проверить любое время на предмет занятости при помощи функций их модуля Slot: покрывает ли слот заданное время (или другой слот), являются ли слоты непересекающимися, или нет и т. д.


Модуль Tempus


Основной модуль экспортирует функции для работы со слотами, как с прерывистой временной шкалой. Можно добавить любой произвольный интервал времени к началу координат, принимая во внимание слоты; проверить, свободен ли этот интервал, или уже занят слотами, получить следующий свободный или следующий занятый слот, инвертировать временную шкалу, и многое другое.


Вот незамысловатый пример из тестов:


slots =  [    Tempus.Slot.wrap(~D|2020-08-07|), # whole day    %Tempus.Slot{      from: ~U|2020-08-08 01:01:00Z|, # one minute      to: ~U|2020-08-08 01:02:00Z|    },    %Tempus.Slot{      from: ~U|2020-08-08 01:03:00Z|, # one minute      to: ~U|2020-08-08 01:04:00Z|    }  ]  |> Enum.into(%Tempus.Slots{})

Если добавить 0 секунд ко времени, уже занятому слотом, вернется первое доступное время после занятого промежутка.


Tempus.add(slots, ~U|2020-08-08 01:01:30Z|, 0, :second)# ~U[2020-08-08 01:02:00Z]

Добавив 70 секунд ко времени, на пять секунд предшествующему первому занятому слоту~U[2020-08-08 01:00:55Z]вернется экземпляр DateTime через пять секунд после второго занятого слота (5sec + занято + 60sec + занято + 5sec):


Tempus.add(slots, ~U|2020-08-08 01:00:55Z|, 70, :second)# ~U[2020-08-08 01:04:05Z]

И так далее. Разумеется, можно добавлять и отрицательные значения.


Слияние наборов слотов


Slots.merge/2 понимает Stream в качестве второго аргумента. На данный момент библиотека не поддерживает слияние и использование двух потоков слотов, но вливание потока в существующие временные интервалы возможно. Это может быть полезно, когда у нас есть короткий список, скажем, праздников, и мы хотим объединить его с повторяющимися слотами, например с выходными.


Все функции, возвращающие Slots и / или Slotгарантированно отдают допустимые объекты (нормализованные, упорядоченные и объединенные по мере необходимости).


Что еще?


Текущая реализация покрывает только наши внутренние потребности, поэтому я был бы рад услышать о том, чего не хватает этой библиотеке и что следует в нее добавить.




Удачных временных интервалов!

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru