7

単純なforループを使用して大量の画像をトリミングし、それらをセル配列に格納しています。私はメッセージを受け取り続けます:

変数croppedSagは、ループが繰り返されるたびにサイズが変わるように見えます。速度を事前に割り当てることを検討してください。

これは、MATLABでコーディングしているときに何度か見たことがあります。私はいつもそれを無視してきましたが、たとえば10,000枚以上の画像がある場合、事前に割り当てるとどれだけ実行時間が長くなるのでしょうか。

また、ドキュメントで事前割り当てについて読んだことがありzeros()、その目的で使用すると書かれています。以下のコードにそれをどのように使用しますか?

croppedSag = {};
for i = 1:sagNum
    croppedSag{end+1} = imcrop(SagArray{i},rect);
end

ドキュメントの例に完全には従いませんでした。

4

1 に答える 1

12

Matlabでは、配列を事前に割り当てることをお勧めします。別の方法は、ループの各反復中に成長する配列を用意することです。要素が配列の最後に追加されるたびに、Matlabは完全に新しい配列を生成し、古い配列の内容を新しい配列にコピーしてから、最後に新しい要素を最後に追加する必要があります。事前割り当てにより、新しいアレイを割り当てて、アレイの既存のコンテンツを新しいメモリにコピーするために時間を費やす必要がなくなります。

ただし、あなたの場合、期待するほど多くのメリットが得られない可能性があります。セル配列を新しい拡大セル配列にコピーする場合、Matlabは実際にはセル配列の内容(画像データ)をコピーする必要はなく、そのデータへのポインターのみをコピーします。

それでも、事前に割り当てない理由はありません(実際に最終的なサイズが事前にわからない場合を除く)。ループの事前に割り当てられたバージョンは次のとおりです。

croppedSag = cell(1, sagNum);
for ii = 1:sagNum
    croppedSag{ii} = imcrop(SagArray{ii}, rect);
end

また、虚数単位を上書きしないように、インデックス変数「i」を「ii」に変更しました。

cellfun関数を使用して、このループを1行で書き直すこともできます。

croppedSag = cellfun(@(im) imcrop(im, rect), SagArray);

参考になるかもしれないブログエントリは次のとおりです。

于 2011-06-02T16:13:22.560 に答える