Нужно обрезать + изменить размер ~300000 файлов. Время выполнения = 4+ дня. Как я могу ускорить мой скрипт?

Я работаю над созданием видео Timelapse. Все фотографии сделаны в формате.jpg, снятом с соотношением сторон 4:3. Разрешение 2592x1944. Я хочу, чтобы все они были 16:9 в 1920x1080.

Я написал небольшой сценарий для этого, но процесс не очень быстрый. Мне потребовалось около 17 минут, чтобы обрезать и изменить размер 750 изображений. У меня есть в общей сложности около 300 000, и, вероятно, я буду работать партиями по 50 000. Это 18 часов 45 минут на пакет и более 4,5 дней вычислений.

Так кто-нибудь знает, как я могу ускорить эту программу?

вот скрипт bash, который я написал:

#!/bin/bash  

mkdir cropped

for f in *.JPG
do
    convert $f -resize 1920x1440 -set filename:name '%t' cropped/'%[filename:name].JPG' #Resize Photo, maintain aspect ratio
    convert cropped/$f -crop 1920x1080+0+$1 -set filename:name '%t' cropped/'%[filename:name].JPG' #Crop to 16:9 aspect ratio, takes in $1 argument for where to begin crop
done

echo Cropping Complete!

Размещение некоторых команд эха до и после каждой строки в цикле показывает, что изменение размера занимает гораздо больше времени, чем обрезка, что, я думаю, не удивительно. Я пытался использовать mogrify -path cropped -resize 1920x1440! $f на месте convert $f -resizeно, похоже, нет большой разницы в скорости.

Итак, каким образом я могу ускорить время выполнения на этом?

БОНУСНЫЕ МОМЕНТЫ, если вы можете показать мне простой способ дать простое представление о ходе выполнения программы (что-то вроде "421 из 750 файлов, 56,13% выполнено").

ДОПОЛНИТЕЛЬНЫЕ БОНУСНЫЕ ТОЧКИ, если вы можете добавить команду для вывода файла.mp4 из каждого кадра, который можно редактировать в такой программе, как SONY Vegas. Мне удалось сделать видеофайлы (.avi), используя mencoder из этих фотографий, но полученное видео не будет работать в любых редакторах видео, которые я пробовал.

3 ответа

Решение

Несколько вещей приходят на ум...

Во-первых, не запускайте ImageMagick дважды на изображение, один раз, чтобы изменить его размер, и один раз, чтобы обрезать его, когда можно будет выполнить обе операции за один раз. Итак, вместо ваших двух convert команды, я бы сделал только одну

convert image.jpg -resize 1920x1440 -crop 1920x1080+0+$1 cropped/image.jpg

Во-вторых, я не вижу, что вы делаете с set команда, что-то с именем файла, но вы можете просто сделать это в оболочке.

В-третьих, я бы предложил вам использовать GNU Parallel (с ним я регулярно обрабатываю до 65 000 изображений в день). Он прост в установке и обеспечит занятость всех этих замечательных процессорных ядер, за которые вы заплатили. Самый простой способ его использования - вместо запуска команд просто отобразить их и направить в parallel

#!/bin/bash  
mkdir cropped

for f in *.jpg
do
   echo convert \"$f\" -resize 1920x1440 -crop 1920x1080+0+$1 cropped/\"$f\"
done  | parallel

echo Cropping Complete!

Наконец, если вы хотите, чтобы индикатор прогресса или указание того, сколько было сделано и что осталось сделать, используйте --eta опция (эта = предполагаемое время прибытия) в parallel и он говорит вам, сколько рабочих мест и сколько времени осталось.

Когда вы будете уверены в parallel возможно, вы запустите весь процесс следующим образом:

parallel --eta convert {} -resize 1920x1440 -crop 1920x1080+0+32 cropped/{} ::: *.jpg

Я создал 750 изображений того же размера, что и ваш, и запустил их таким образом, и iMac моей средней спецификации 55 секунд, чтобы изменить размер и обрезать партию - YMMV. Пожалуйста, добавьте комментарий и скажите, как вы продвинулись - сколько времени занимает обработка parallel,

Во-первых, чтобы ускорить процесс, не выводите данные на экран, а отображайте их в файл, и если вы хотите узнать статус чтения файла (это легко сделать с помощью команды tail), серьезно, это уже будет быстрее. Однако это не похоже на реальное узкое место вашей программы. Главное, что я могу порекомендовать, это запустить его параллельно, есть ли причина, по которой вы не можете обрезать + изменить размер рис. 1000 перед рис. № 4? Если нет, то измените скрипт, чтобы получить некоторый параметр, который определяет, с какими файлами он должен работать, а затем запустите его несколько раз с другими параметрами, это должно сократить время примерно на столько ядер ЦП, сколько у вас есть (минус несколько жестких дисков. Время ввода / вывода). Что касается вашего первого бонусного вопроса, вы можете сделать вариант этого кода

TOTAL=`ls -1|wc -l` #get the total number of files (you can change this to the files parameter I mentioned above
SOFAR=0 #How many files you've done so far
for f in *.JPG
do
    ((SOFAR++)) 
    echo "done so far $SOFAR out of $TOTAL"
done

Использовать

-define jpeg:size=1920x1440

опция вместе с -resize. Если у вас более старая версия ImageMagick (извините, я точно не знаю, когда изменился синтаксис), используйте

-size 1920x1440

опция вместе с -resize.

Другие вопросы по тегам