{
    "version": "https:\/\/jsonfeed.org\/version\/1",
    "title": "Математик среди биологов: заметки с тегом imagemagick",
    "_rss_description": "Я немного умею складывать, но от вычитания у меня всегда кружится голова",
    "_rss_language": "ru",
    "_itunes_email": "",
    "_itunes_categories_xml": "",
    "_itunes_image": "",
    "_itunes_explicit": "",
    "home_page_url": "https:\/\/antonlyakh.ru\/blog\/tags\/imagemagick\/",
    "feed_url": "https:\/\/antonlyakh.ru\/blog\/tags\/imagemagick\/json\/",
    "icon": false,
    "author": {
        "name": "Антон Лях",
        "url": "https:\/\/antonlyakh.ru\/blog\/",
        "avatar": false
    },
    "items": [
        {
            "id": "465",
            "url": "https:\/\/antonlyakh.ru\/blog\/all\/kombiniruem-kadry-dvizheniya-protist-v-mnogosloynye-tify\/",
            "title": "Комбинируем кадры движения протист в многослойные тифы",
            "content_html": "<p>В первой заметке рассказал, <a href=\"\/blog\/all\/uluchshaem-kachestvo-video-dvizheniya-protist-i-narezaem-ego-na\/\">как улучшить качество видео и нарезать его на кадры<\/a>.<\/p>\n<p><br\/><\/p>\n<p>Это вторая техническая заметка из <a href=\"\/blog\/all\/seriya-zametok-ob-analize-traektoriy-dvizheniya-protist\/\">серии об анализе траектории движения протист<\/a>. В ней поговорим, как объединить кадры видео в пакеты по сто кадров и сохранить их в многослойных <abbr>тифах<\/abbr>.<\/p>\n<p>Напомню, что шаманю над видео по двум причинам: из-за скрипта для выделения траекторий, который плохо понимает видеоформаты, но отлично работает с <abbr>тифами<\/abbr>, а также из-за небольшой оперативки, которой не хватает для обработки тяжелых <abbr>тифов<\/abbr>. Поэтому приходится их резать.<\/p>\n<p><br\/><\/p>\n<p><b><big>В конце заметки приведена ссылка на скрипт, который преобразует <abbr>mov<\/abbr> в многослойные <abbr>tif<abbr><\/big><\/b><\/p>\n<h3>Последовательность действий<\/h3>\n<p>Буду использовать <abbr><a href=\"https:\/\/imagemagick.org\/\">ИмеджМаджик<\/a><\/abbr> и <a href=\"https:\/\/ss64.com\/nt\/\">батч-скрипт Виндоус<\/a>. (Вместо последнего можно взять <abbr>Поверскрипт<\/abbr>, для Линукса — <abbr>баш<\/abbr>, но это вы уже сами :).<\/p>\n<p>Скрипт разделяет <abbr>тифы<\/abbr> на группы: 1...100, 100...200, 200...300, ... и объединяет файлы из каждой группы  в многослойный <abbr>тиф<\/abbr>.<\/p>\n<p>Последний <abbr>тиф<\/abbr> группы совпадает с первым <abbr>тифов<\/abbr> седующей группы: 1...100≡100...200≡200... Так сделано для того, чтобы потом программа смогла правильно соединить кусочки траекторий, выделенные в группах, в целые траектории.<\/p>\n<h4>Инициализируем вспомогательные переменные<\/h4>\n<p>Итак, мы получили серию <abbr>тифов<\/abbr>, каждый из которых хранит один кадр. <abbr>Тифы<\/abbr> лежат в отдельном каталоге и шаблонно пронумерованы:<\/p>\n<ul>\n<li><kbd>frame_0001.tif, frame_0002.tif, frame_0003.tiff, ...<\/kbd><\/li>\n<\/ul>\n<p>Укажем в батч-скрипте название каталога, префикс <abbr>тиф<\/abbr>-файлов и префикс многослойных <abbr>тифов<\/abbr>.<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">rem Инициализируем вспомогательные переменные\r\n:initialization\r\n    set tif_file_prefix=frame_\r\n    set group_file_prefix=merged_\r\n    set tifs_dir=tifs<\/code><\/pre><h4>Посчитаем число тифов<\/h4>\n<p>Мы не знаем, сколько файлов у нас есть. Поэтому воспользуемся <a href=\"https:\/\/superuser.com\/a\/1530244\/521108\">советом<\/a> и напишем скрипт:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">rem Считает число тифов в заданном каталоге\r\n:calc-tifs-number\r\n    cd %tifs_dir%\r\n    dir *.tif \/A:-D \/B 2&gt;nul | find \/c \/v &quot;&quot; &gt; tmp\r\n    set \/p tifs_numb=&lt;tmp\r\n    set \/a tifs_numb+=0\r\n    del tmp\r\n    cd ..<\/code><\/pre><p>Скрипт переходит в каталог с тифами, записанном в переменной <kbd>tifs_dir<\/kbd>, считает число тифов и запоминает его в файле <kbd>tmp<\/kbd>, загружает значение из этого файла в переменную <kbd>tifs_numb<\/kbd> и удаляет <kbd>tmp<\/kbd>-файл.<\/p>\n<p>Подсчет и сохранение числа в файл выполняет команда<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">dir *.tif \/A:-D \/B 2&gt;nul | find \/c \/v &quot;&quot; &gt; tmp<\/code><\/pre><p>где опция<\/p>\n<blockquote>\n<p><kbd>*.tif<\/kbd> выбирает только <abbr>тиф<\/abbr>-файлы;<br \/>\n<kbd>\/A:-D<\/kbd> убирает из подсчета каталоги и оставляет только файлы;<br \/>\n<kbd>\/B<\/kbd> выводит только названия файлов;<br \/>\n<kbd>2>nul<\/kbd> не выводит строки с ошибками;<br \/>\n<kbd>|<\/kbd> передает полученный список файлов следующей команде;<br \/>\n<kbd>find \/c \/v &quot;&quot;<\/kbd> считает число строк в списке файлов;<br \/>\n<kbd>> tmp<\/kbd> запоминает полученное число в файл <kbd>tmp<\/kbd>.<\/p>\n<\/blockquote>\n<p>Прочие команды скрипта очевидны.<\/p>\n<h4>Вычисляем количество групп файлов и число файлов в последней группе<\/h4>\n<p><br\/><\/p>\n<pre class=\"e2-text-code\"><code class=\"\">set \/a num_groups=1+(%tifs_numb%-1)\/100\r\nset \/a numb_in_last_group=(%tifs_numb%)%%100<\/code><\/pre><h4>Объединяем тифы каждой группы в один многослойный тиф<\/h4>\n<p>В <abbr>Имеджмаджик<\/abbr> есть утилита <kbd>convert<\/kbd>, которая с ключом <kbd>-adjoin<\/kbd> объединяет <abbr>тифы<\/abbr> в один многослойный.<\/p>\n<blockquote>\n<p><kbd>convert 0001.tif 0002.tif ... 100.tif -adjoin merged_1-100.tif <\/kbd><br \/>\n<kbd>convert 0100.tif 0101.tif ... 200.tif -adjoin merged_100-200.tif <\/kbd><br \/>\n...<\/p>\n<\/blockquote>\n<p>Параметрами команды служат названия файлов. В первой группе у нас сто тифов, во всех остальных, кроме последней, сто один тиф, в последней — оставшиеся файлы.<\/p>\n<p>Для формирования cписка файлов используем цикл, после завершения которого все <abbr>тифы<\/abbr> будут объединены в многослоные <abbr>тифы<\/abbr>.<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">set \/a file_index=0\r\nset \/a group_index=0\r\n\r\ncd %tifs_dir%\r\n    rem Пробегаем по каждой группе\r\n    for \/l %%G in (1,1,%num_groups%) do call :loop_groups %%G\r\ncd ..\r\n\r\necho All tifs have been merged into multilayered tifs\r\npause\r\n\r\ngoto :eof<\/code><\/pre><p>Цикл вызывает подпрограмму <kbd>:loop_groups<\/kbd>, где и происходит слияние. Подпрограмма принимает номер группы, вычисляет для нее номера первого и последнего файла, формирует список файлов с этими номерами и, в итоге, объединяет их в многослойный <abbr>тиф<\/abbr>.<\/p>\n<pre class=\"e2-text-code\"><code class=\"bash\">\r\n:loop_groups\r\n\r\nrem Определям начальный и конечный номер файла в группе\r\nset \/a start_index=group_index*100\r\n\r\nif %1 EQU %num_groups% (\r\n    rem Это последняя группа\r\n    set \/a finish_index=start_index+%numb_in_last_group%\r\n) else (\r\n    rem Это не последняя группа\r\n    set \/a finish_index=start_index+100\r\n)\r\n\r\nif %start_index% EQU 0 set \/a start_index=1\r\n\r\n\r\nrem Формируем список файлов.\r\nrem Для этого перебираем номера файлов от start_index до finish_index\r\nrem и конструируем название файла с каждым номером в пп loop_files\r\nset file_list=\r\nfor \/l %%H in (%start_index%,1,%finish_index%) do call :loop_files %%H\r\n\r\n\r\nrem Задаем имя результирующего многослойного тифа\r\nset merged_file=%group_file_prefix%_%start_index%-%finish_index%.tif\r\n\r\n\r\nrem Конвертируем\r\nconvert %file_list% -adjoin %merged_file%\r\n\r\n\r\nrem Переходим к следующей группе\r\nset \/a group_index=group_index+1\r\n\r\ngoto :eof\r\n<\/code>\n<\/pre>\n<p>Сам список файлов поэлементно строится в подпрограмме <kbd>:loop_files<\/kbd>. Она принимает номер файла, дополняет его нулями, добавляет к нему префикс и помещает в конец списка (строки).<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">:loop_files\r\nrem Добавляет ведущие нули к индексу файла\r\nset &quot;file_index=0000%1&quot;\r\nset &quot;file_index=%file_index:~-4%&quot;\r\n\r\nrem Дополняет файл префиксом\r\nset file_name=%tif_file_prefix%_%file_index%.tif\r\n\r\nrem Добавляет название файла в конец списка\r\nset &quot;file_list=%file_list%%file_name% &quot;\r\n\t\r\ngoto :eof<\/code><\/pre><h3>Итоговый скрипт<\/h3>\n<p>Готовый батч-скрипт пробразует <abbr>mov<\/abbr> в многослойные <abbr>tiff<\/abbr>.<\/p>\n<p>Он использует код из двух заметок и:<\/p>\n<ul>\n<li>спрашивает название <abbr>мув<\/abbr>-файла с видео;<\/li>\n<li>спрашивает, нужно ли осветлить видео;<\/li>\n<li>спрашивает название каталога, куда следует поместить многослойные тифы;<\/li>\n<li>спрашивает, нужно ли удалить тифы с отдельными кадрами после завершения работы.<\/li>\n<\/ul>\n<p><br\/><\/p>\n<p><span style=\"display:inline-block; background-color:#40BA9B; padding:8px 12px; border-radius:2px\"><a href=\"\/download\/?mov-to-tifs\" style=\"color:#fff; font-weight:bold\">Скачать скрипт mov-to-tifs<\/a><\/span><\/p>\n<p><span style=\"color:cadetblue\">Скрипт распространяется бесплатно, как есть и может быть запущен на любом количестве машин. Вы соглашаетесь с ипользованием скрипта на свой страх и риск. Автор скрипта не несет ответственности ни за какие сбои, неверную работу, удаление или изменение пользовательских данных.<\/span><\/p>\n<p><br\/><\/p>\n<p>Для работы скрипта необходимо установить <a href=\"https:\/\/imagemagick.org\/\">ImageMagick<\/a>.<\/p>\n<p><br\/><\/p>\n<p>Вопросы, связанные с функционирование скрипта, задавайте в комментариях.<\/p>\n",
            "date_published": "2023-02-24T22:59:48+03:00",
            "date_modified": "2023-02-24T22:59:21+03:00",
            "_date_published_rfc2822": "Fri, 24 Feb 2023 22:59:48 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "465",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        }
    ],
    "_e2_version": 3559,
    "_e2_ua_string": "E2 (v3559; Aegea)"
}