1 заметка с тегом

батч-файл

Комбинируем кадры движения протист в многослойные тифы

В первой заметке рассказал, как улучшить качество видео и нарезать его на кадры.


Это вторая техническая заметка из серии об анализе траектории движения протист. В ней поговорим, как объединить кадры видео в пакеты по сто кадров и сохранить их в многослойных тифах.

Напомню, что шаманю над видео по двум причинам: из-за скрипта для выделения траекторий, который плохо понимает видеоформаты, но отлично работает с тифами, а также из-за небольшой оперативки, которой не хватает для обработки тяжелых тифов. Поэтому приходится их резать.


В конце заметки приведена ссылка на скрипт, который преобразует mov в многослойные tif

Последовательность действий

Буду использовать ИмеджМаджик и батч-скрипт Виндоус. (Вместо последнего можно взять Поверскрипт, для Линукса — баш, но это вы уже сами :).

Скрипт разделяет тифы на группы: 1...100, 100...200, 200...300, ... и объединяет файлы из каждой группы в многослойный тиф.

Последний тиф группы совпадает с первым тифов седующей группы: 1...100≡100...200≡200... Так сделано для того, чтобы потом программа смогла правильно соединить кусочки траекторий, выделенные в группах, в целые траектории.

Инициализируем вспомогательные переменные

Итак, мы получили серию тифов, каждый из которых хранит один кадр. Тифы лежат в отдельном каталоге и шаблонно пронумерованы:

  • frame_0001.tif, frame_0002.tif, frame_0003.tiff, ...

Укажем в батч-скрипте название каталога, префикс тиф-файлов и префикс многослойных тифов.

rem Инициализируем вспомогательные переменные
:initialization
    set tif_file_prefix=frame_
    set group_file_prefix=merged_
    set tifs_dir=tifs

Посчитаем число тифов

Мы не знаем, сколько файлов у нас есть. Поэтому воспользуемся советом и напишем скрипт:

rem Считает число тифов в заданном каталоге
:calc-tifs-number
    cd %tifs_dir%
    dir *.tif /A:-D /B 2>nul | find /c /v "" > tmp
    set /p tifs_numb=<tmp
    set /a tifs_numb+=0
    del tmp
    cd ..

Скрипт переходит в каталог с тифами, записанном в переменной tifs_dir, считает число тифов и запоминает его в файле tmp, загружает значение из этого файла в переменную tifs_numb и удаляет tmp-файл.

Подсчет и сохранение числа в файл выполняет команда

dir *.tif /A:-D /B 2>nul | find /c /v "" > tmp

где опция

*.tif выбирает только тиф-файлы;
/A:-D убирает из подсчета каталоги и оставляет только файлы;
/B выводит только названия файлов;
2>nul не выводит строки с ошибками;
| передает полученный список файлов следующей команде;
find /c /v "" считает число строк в списке файлов;
> tmp запоминает полученное число в файл tmp.

Прочие команды скрипта очевидны.

Вычисляем количество групп файлов и число файлов в последней группе


set /a num_groups=1+(%tifs_numb%-1)/100
set /a numb_in_last_group=(%tifs_numb%)%%100

Объединяем тифы каждой группы в один многослойный тиф

В Имеджмаджик есть утилита convert, которая с ключом -adjoin объединяет тифы в один многослойный.

convert 0001.tif 0002.tif ... 100.tif -adjoin merged_1-100.tif
convert 0100.tif 0101.tif ... 200.tif -adjoin merged_100-200.tif
...

Параметрами команды служат названия файлов. В первой группе у нас сто тифов, во всех остальных, кроме последней, сто один тиф, в последней — оставшиеся файлы.

Для формирования cписка файлов используем цикл, после завершения которого все тифы будут объединены в многослоные тифы.

set /a file_index=0
set /a group_index=0

cd %tifs_dir%
    rem Пробегаем по каждой группе
    for /l %%G in (1,1,%num_groups%) do call :loop_groups %%G
cd ..

echo All tifs have been merged into multilayered tifs
pause

goto :eof

Цикл вызывает подпрограмму :loop_groups, где и происходит слияние. Подпрограмма принимает номер группы, вычисляет для нее номера первого и последнего файла, формирует список файлов с этими номерами и, в итоге, объединяет их в многослойный тиф.


:loop_groups

rem Определям начальный и конечный номер файла в группе
set /a start_index=group_index*100

if %1 EQU %num_groups% (
    rem Это последняя группа
    set /a finish_index=start_index+%numb_in_last_group%
) else (
    rem Это не последняя группа
    set /a finish_index=start_index+100
)

if %start_index% EQU 0 set /a start_index=1


rem Формируем список файлов.
rem Для этого перебираем номера файлов от start_index до finish_index
rem и конструируем название файла с каждым номером в пп loop_files
set file_list=
for /l %%H in (%start_index%,1,%finish_index%) do call :loop_files %%H


rem Задаем имя результирующего многослойного тифа
set merged_file=%group_file_prefix%_%start_index%-%finish_index%.tif


rem Конвертируем
convert %file_list% -adjoin %merged_file%


rem Переходим к следующей группе
set /a group_index=group_index+1

goto :eof

Сам список файлов поэлементно строится в подпрограмме :loop_files. Она принимает номер файла, дополняет его нулями, добавляет к нему префикс и помещает в конец списка (строки).

:loop_files
rem Добавляет ведущие нули к индексу файла
set "file_index=0000%1"
set "file_index=%file_index:~-4%"

rem Дополняет файл префиксом
set file_name=%tif_file_prefix%_%file_index%.tif

rem Добавляет название файла в конец списка
set "file_list=%file_list%%file_name% "
	
goto :eof

Итоговый скрипт

Готовый батч-скрипт пробразует mov в многослойные tiff.

Он использует код из двух заметок и:

  • спрашивает название мув-файла с видео;
  • спрашивает, нужно ли осветлить видео;
  • спрашивает название каталога, куда следует поместить многослойные тифы;
  • спрашивает, нужно ли удалить тифы с отдельными кадрами после завершения работы.


Скачать скрипт mov-to-tifs

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


Для работы скрипта необходимо установить ImageMagick.


Вопросы, связанные с функционирование скрипта, задавайте в комментариях.