非効率2

GraphicsMagicのMagick++のImage::rotateで、3000*2400 48bitの画像(容量は約42MB)
を処理すると、500MB近くメモリを消費してしまう。


RotateImage中のBorderImage中のFrameImageの中のSetImagePixelsの引数の、
frame_image->columns,heightが、元の画像の横幅、縦幅より異様に大きいので、
それで確保するメモリの量が非常に大きくなってしまってるんだろうか。。


GraphicsMagickが、巨大な画像の処理用の事を考えて作られていないのかなぁ。。
それとも使い方が悪いのだろうか。。


http://faqs.jmas.co.jp/FAQs/graphics/algorithms-faq
を読んでみると、画像の回転アルゴリズムには、主に2種類あるようで、


一番簡単な方法は、回転マトリクスを反転させたものを利用して、ターゲットの
ピクセルを総当りで回って、元の画像からピクセルを取っていく方法。


もっと良い方法は、
R(T) = { { cos(T), -sin(T) }, { sin(T), cos(T) } }

R(T) = M1(T) * M2(T) * M3(T)

M1(T) = { { 1, -tan(T/2) }, { 0, 1 } }
M2(T) = { { 1, 0 }, { sin(T), 1 } }
M3(T) = { { 1, -tan(T/2) }, { 0, 1 } }
という3パスのやり方のようだ。


他の速い方法としては、最初に列を保つ回転をやって、その後に行を保つ回転を
行うのだとか。ん?2回で済むの??

  • -

なぜ総当りで逆算するやり方より、shearを繰り返す方法のが
処理コストが掛からないのか、おつむが悪くて理解がまだ出来ていないけれど、
CodeProjectに、このアルゴリズムの実装例が投稿されていて、
http://www.codeproject.com/bitmap/rotatebyshear.asp
それをAnton Treskunovという人が改良したのが、
http://anton.treskunov.net/
で公開されていた。


自分でもそれを改造して色んな画像に適用してパフォーマンスを計ってみよう。
なんか理解が出来てないし。。


GraphicsMagickのRotateImageはshearを繰り返す方法で作られているけれど、
なんかメモリ食いすぎるので使えない。。