2016-10-07 10 views
0

私は、タイムラプス映画の画像の束を処理するためにbashスクリプトを使用します。このメソッドはシャッタードラッグと呼ばれ、私はすべての画像の移動平均を作成しています。次のスクリプトが正常に動作します:読み書き可能な画像処理スクリプトのパフォーマンスを改善するにはどうすればよいですか?

#! /bin/bash 
totnum=10000 
seqnum=40 
skip=1 
num=$(((totnum-seqnum)/1)) 
i=1 
j=1 
while [ $i -le $num ]; do 
    echo $i 
    i1=$i 
    i2=$((i+1)) 
    i3=$((i+2)) 
    i4=$((i+3)) 
    i5=$((i+4)) 
    ... 
    i37=$((i+36)) 
    i38=$((i+37)) 
    i39=$((i+38)) 
    i40=$((i+39)) 
    convert $i1.jpg $i2.jpg $i3.jpg $i4.jpg $i5.jpg ... \ 
      $i37.jpg $i38.jpg $i39.jpg $i40.jpg \ 
      -evaluate-sequence mean ~/timelapse/Images/Shutterdrag/$j.jpg 
    i=$((i+$skip)) 
    j=$((j+1)) 
done 

しかし、私はこのスクリプトは大きな平均窓(画像あたり1S)を使用して画像の多くを処理するのに非常に長い時間を要することに気づきました。私は、これはバックグラウンドで多くの読み書きが原因で起こっていると思います。

このスクリプトの速度を上げることは可能ですか?例えば、画像をメモリに格納し、すべての反復で最初の画像を削除し、最後の画像のみをロードすることによって、

私はmpr:{label}のimagemagickの機能を発見しましたが、これは適切なアプローチではないと思います。convertコマンドの後にメモリがクリアされますか?

+1

各画像を何度も読み取るように見えるので、RAMディスク(どのOSを使用していますか?)を作成し、すべてのJPEGファイルをRAMディスクの「MPC」形式ファイルに変換して、 GNU Parallelを使ってください。 –

+0

Ubuntu 15.10は私が使用しているOSです。 RAMディスクを簡単にセットアップして使用する方法はありますか? – Markus

+0

ここにある例http://www.hecticgeek.com/2015/12/create-ram-disk-ubuntu-linux/ –

答えて

3

提案1 - RAMディスク

起動する前にすべてのファイルをRAMディスクに保存したい場合は、I/O速度が非常に高くなるはずです。使用MPCフォーマット

ので、前のステップを行っていると仮定すると、MPCフォーマットにすべてのあなたのJPEGファイルを変換する -

sudo mkdir /RAMdisk 
sudo mount -t tmpfs -o size=1024m tmpfs /RAMdisk 

が提案2:

ので、1ギガバイトRAMディスク、使用することをRAMディスク上のファイル。 MPCファイルは、MPCがImageMagickと同じフォーマットであるため、CPUがメモリを使わずにディスク上で使用するため、コストのかかるJPEGデコードを行う必要がなく、メモリに直接書き込むことができます。

私はGNUで、このようなパラレルいることだろう。-Xconvertプロセスの負荷を作成せずにmogrifyにできるだけ多くのファイルを渡し

parallel -X mogrify -path /RAMdisk -fmt MPC ::: *.jpg 

-pathに出力ファイルがどこにあるかが示されます。 -fmt MPCは、mogrifyを入力ファイルをMPC形式(Magick Pixel Cache)のファイルに変換します。このファイルでは、ループ内の次のconvertコマンドは高価なJPEGデコードではなく純粋なDMAで読み取ることができます。

GNUパラレルがない場合は、先頭にparallel -X:::を付けないでください。

提案3 - 利用GNUパラレルます。また、並行してchepnerのコード@実行することができ

...基本的に

for ...; do 
    echo convert ... 
done | parallel 

、私はすべてのコマンドをエコーの代わりに、それらを実行していますリストは、GNUパラレルによって実行されます。これは、Ericが提案したようにImageMagickをOpenMPでコンパイルできない場合に特に便利です。

parallelの後に--etaなどのスイッチを使用して再生すると、完了までにどれくらいの時間がかかりますか?--progressです。また、どのように大きなあなたのマシンに応じて-j 2または-j4で実験。


私はいくつかのベンチマークを楽しんだだけです。まず、640x480でランダムノイズの250枚のJPEG画像を作成し、chepnerのコードを「そのまま」 - 2分27秒かかりました。


はその後、私は画像の同じセットを使用し、これにループを変更:

for ((i=1, j=1; i <= num; i+=skip, j+=1)); do 
    echo convert "${files[@]:i:seqnum}" -evaluate-sequence mean ~/timelapse/Images/Shutterdrag/$j.jpg 
done | parallel 

時間が35秒に下って行きました。


は、その後、私はそれがあったかループバックを入れて、代わりにJPEGのMPCにすべての入力ファイルを変更し、時間が36秒に下って行きました。


最後に、私は、上記のようにMPCフォーマット GNUパラレルを使用し、時間が19秒に低下しました。

私はあなたとは別のOS(非常に高速なNVMEディスクを持っています)としてRAMディスクを使用しませんでしたが、それは非常に助けになるでしょう。 RAMdiskに出力ファイルを書き込むことも、MPC形式で書き込むこともできます。

幸運にも、あなたはどうしたらいいのか教えてください!

+0

ねえ、私はついにその話題を調べる時間がありました。私はあなたの提案を使用し、それは多くの処理を改善しました。私はRAMディスクを4GBにすることを選択しましたが、これは2MP解像度の約150画像にしか適合しません。したがって、私は画像の束をロードし、これらを処理し、後でRAMディスクからそれらを削除するループを使用しています。以前は1,11/img(SSD)でしたが、現在は0,42/img(RAM上のMPC)(40 img windows)です。 Mogrifyは '-format MPC'を使用します。あなたの時間と助けてくれてありがとう! – Markus

+0

優秀!私はあなたのために働いてうれしいです。あなたのプロジェクトに幸運。 –

2

これを高速化するためにbashに行うことは何もありません。 convertがしなければならない実際のIOを除いてすべてはかなり簡単です。しかし、あなたは大幅にスクリプトを簡素化することができます:RAMディスク内のファイルを保存する

#! /bin/bash 
totnum=10000 
seqnum=40 
skip=1 
num=$(((totnum-seqnum)/1)) 


# Could use files=(*.jpg), but they probably won't be sorted correctly 
for ((i=1; i<=totnum; i++)); do 
    files+=($i.jpg) 
done 

for ((i=1, j=1; i <= num; i+=skip, j+=1)); do 
    convert "${files[@]:i:seqnum}" -evaluate-sequence mean ~/timelapse/Images/Shutterdrag/$j.jpg 
done 

は確かに役立つだろうが、それは、このサイトの範囲を超えています。 (もちろん、十分なRAMがあれば、最初に読み込んだ後、ディスクキャッシュにファイルを保存しておかなければならないため、RAMディスクをプリロードせずに後続の読み込みを高速化する必要があります)

+0

ありがとうございます、これは見た目が良くなりました! – Markus

関連する問題