Нужно обрезать + изменить размер ~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.