ImageMagick の例 --
画像の歪み

目次
ImageMagick の例 序文と目次
一般的な歪みテクニック
 
アフィンマトリックス変換(別サブディレクトリ)
 
一般化された歪み演算子
 
歪み手法の紹介
 
アフィン(3点)歪み手法
4点歪み手法
多項式 歪み
円形および放射状の歪み手法
射影歪み
多点および自由形状歪み
初期の頃からIMが提供してきた、組み込みの単純な画像のラッピングと歪み演算子を見てきたので、ここではさらに深く、内部のメカニズムと画像のより複雑な数学的歪みを見ていきます。このより深い理解から、より一般的な画像歪み演算子を見ていきます。これには、複雑な回転、スケーリング、シアリングから、パースペクティブまたは3D歪み、円弧への、円弧からのワープ、カメラレンズの歪み、そして最後に、より一般的なモーフのような歪みまでが含まれます。

一般的な歪みテクニック

IMが提供する単純な歪み演算子を紹介したので、少し立ち止まって、詳細を見て、画像歪みが実際にどのように機能するか、そしてそれらをどのように使用できるかを改善しましょう。後で、ImageMagickに直接組み込まれていない方法を含め、画像を歪ませるためのさらに複雑な方法に進みます。画像プロセッサが画像を歪ませるには、いくつかの基本的な方法しかありません。たとえば、単純な歪み演算子は、ピクセル交換によって実現されます。つまり、個々のピクセル、またはピクセルの行と列全体が、単に交換されて画像の反転ロール転置、さらには長方形回転されます。色の変更は行われず、ピクセル数は同じままです。画像の歪みを変更する次の方法は、IMが画像シアや上記の波歪みで実行するように、ピクセルの列と行を水平または垂直にシフトまたはシアリングすることです。シアは、任意の角度で画像を回転する1つの方法を提供します。これは非常に高速であるはずです。ただし、ピクセルシフト手法は、これらの基本的な歪みに限定されます。たとえば、画像のサイズを別のサイズにスケーリングすることはできません。また、元のソース画像でカバーされていなかった結果の画像の領域の処理をほとんど制御できません。上記で述べた関数では、IMは不足している領域を現在の背景色に設定するだけです。画像をより一般的な方法で歪ませることができるようにするには、逆ピクセルマッピングとして知られる、より一般的な歪みテクニックを使用する必要があります。たとえば、この方法は、爆縮渦巻き画像などの、より複雑な円形歪みで使用されます。

順方向または直接ピクセルマッピング

画像を歪ませようとするときに人々が最初に考えるのは、ソース画像の各ピクセルを取得し、それを宛先画像の新しい場所に直接移動することです。実際、これは、単純な歪み画像トリミング、さらにはベクター画像を歪ませる場合にも実際に起こることです。各ピクセル(または座標)は、最終画像の新しい位置に移動するだけです。残念ながら、これは単純な歪み以外のことをしようとすると問題が発生します。たとえば、ここでは、小さな画像の列挙されたピクセルリストを取り、各ピクセルの場所を変更して、新しい場所に回転させます。

  # Rotate by 17 degrees -- get the Sine and Cosine of this angle
  sin=`magick xc: -format "%[fx:sin( 17 *pi/180)]" info:`
  cos=`magick xc: -format "%[fx:cos( 17 *pi/180)]" info:`

  # For each Pixel, rotate that pixels coordinates
  magick koala.gif  txt:- |  sed '2,$ s/,/:/' |\
    gawk -F: 'NR == 1 { print }
              NR > 1 {  x = $1-32;    y = $2-32;
                        nx = int( c*x - s*y + 32 );
                        ny = int( s*x + c*y + 32 );
                        printf( "%d,%d: %s\n", nx, ny, $3 );
              }' s=$sin c=$cos - |\
      magick -background black  txt:-   koala_rotated_direct.gif
[IM Output]
歪みはわずか17度の単純な回転ですが、結果はまったく良くありません。まず、各新しいピクセルの場所は浮動小数点値ですが、ピクセルは整数グリッドにのみ存在できるため、上記では結果の非整数部分を単に破棄しています。2番目の問題は、ピクセルが着地しなかった穴で結果が満たされていることです。これは3番目の問題を引き起こします。見えないかもしれませんが、結果の画像のすべての穴について、2つのピクセルが配置された別の場所も見つかります。つまり、同じ場所に複数のピクセルがあります。どのピクセル値を使用する必要がありますか?上記のIMでは、ある場所に対して定義された最後のピクセルを使用しました。言い換えれば、結果の画像は不完全であり、宛先の各ピクセルは本来あるべき場所になく、複数のピクセルがある場合もあれば、ピクセルがまったくない場合もあります。これらは深刻な問題であり、ソース画像から宛先画像にピクセルを直接順方向マッピングする場合は、簡単には解決できない問題です。つまり、それが機能しないと言っているわけではなく、多くの研究論文では「スプラッティング」として知られる手法の使用について言及しています。基本的に、各入力ピクセルを取得し、その場所を変換してから、新しい場所でピクセル色を適切に拡散および混合して描画します。この手法は、現実世界のオブジェクトの3Dデジタル化を扱う場合に特に役立ちます。ここでは、既知の色の表面点の「クラウド」があります。ユーザーに表示される任意の点は、最終的な画像を作成するために画面に単純に「スプラット」されます。十分な点があれば、画像は完全に表示されます。インタラクティブな3Dコントロールを使用すると、非常にうまく機能し、非常に高速です。ただし、3次元点のスプラッティングは、2次元ラスター画像を処理するIMの範囲を超えています。

逆ピクセルマッピング

宛先画像にピクセルをマッピングするのではなく、宛先画像の各ピクセルの座標をソース画像の対応する場所にマッピングし、ソース画像からそのピクセルが含めるべき色をルックアップできます。これは逆ピクセルマッピングと呼ばれ、ほとんどすべての画像歪みプログラムが行っていることです。宛先画像のすべてのピクセルが処理されるため、宛先のすべてのピクセルが1つの色だけを取得することを保証できます。したがって、各宛先ピクセルの「ソース」の場所を把握できる限り、想像できる数学的公式を使用してソース画像を宛先画像に歪ませることができます。
[Diagram]
要約すると、歪みマッピング(逆マッピング)は次のことを行います。
For each pixel (I,J) in the destination or output image
   Map the I,J pixel position to a X,Y pixel position in the original image
   Look up the Color of the original image at position X,Y
       Using color interpolation, work out the appropriate color.
       Or the virtual-pixel setting, if it misses the actual source image.
   Set the destination images color for pixel I,J
上記では変数名「I,J」と「X,Y」を使用しましたが、これらの変数はFX DIY演算子で通常使用する変数名にマッピングされるためです。たとえば、ここでは、以前に試みたのと同じ17度の回転をシミュレートしますが、今回は「-fx」演算子を使用して、ソース画像のその場所に最も近いピクセルをルックアップします。

  # Rotate by 17 degrees -- get the Sine and Cosine of this angle
  sin=`magick xc: -format "%[fx:sin( 17 *pi/180)]" info:`
  cos=`magick xc: -format "%[fx:cos( 17 *pi/180)]" info:`
  cx=37; cy=37;   # center of rotation

  magick -size 75x75 xc:       koala.gif  \
          -virtual-pixel Black  -interpolate NearestNeighbor \
          -fx "ii = i - $cx;   jj = j - $cy;
               xx =  $cos*ii +$sin*jj + $cx;
               yy = -$sin*ii +$cos*jj + $cy;
               v.p{xx,yy}" \
          koala_rotated_fx.gif
[IM Output]
DIYアフィン歪みマッピングに関するサブセクションで、上記のDIY例の詳細を知ることができます。ご覧のとおり、宛先のすべてのピクセルの色をルックアップするため、画像に「穴」はなくなりました。それでもあまり良く見えませんが、それは各ピクセルに配置する色を正確に調整することの問題です。つまり、逆ピクセルマッピングは、穴や重なり合うピクセルを生成しません。各ピクセルには、完全な画像を生成する適切に定義された色があります。
順方向マッピングと逆方向マッピングの区別は重要です。ほとんどの数学的変換は、単一のソース(X,Y)位置を宛先(I,J)位置にマッピングする順方向マッピングとして定義されているからです。実際、「順方向マッピング」はベクターグラフィックスや、線の両端をマッピングして線を描画するだけで済む線描画には適しています。特に回転のように線が直線であり続ける線形変換の場合に当てはまります。実際、PostScriptやSVGのようなすべてのベクターベース言語で行われていることです。しかし、一般的なラスター画像の場合、画像を歪ませて、宛先画像のすべてのピクセルを確実に「塗りつぶす」ことができるように、「逆方向マッピング」を使用する必要があります。たとえば、上記の2つのケースで座標をマッピングするために使用された数学を見ると、ほとんど同じように見えることがわかるでしょう。「回転」の逆マッピングは、反対方向の別の「回転」です。よく見ると、「sin」定数が順方向マッピングされたバージョンでは否定されていることがわかります。それだけで回転の方向を反転させるのに十分です。この詳細は重要かつ決定的です。問題は、すべての順方向マッピング変換が逆変換としてうまく機能するわけではないということです。一部の順方向マッピングは、実際には単純な直接的な逆マッピングを持ちません。これは、できないということではなく、単純ではないということです。一方、一部の画像変換は逆マッピングとして非常にうまく機能しますが、単純な順方向マッピングはありません。したがって、逆マッピング手法を使用することは、数学的に見ると良い面も悪い面もあるということです。
参考までに、上記と同じ画像の回転を正確に行い、全く同じ結果をより高速に生成する一般歪曲、SRTメソッドを使用した場合の、より高速な同等処理を以下に示します。ここでも、色のルックアップは「点」補間を使用することにより、マッピングされた位置に最も近いピクセルの色のみに制限されています。つまり、(ソース画像を「見逃した」場合を除き)新しい色が画像に追加されることはありませんが、深刻なエイリアシング効果も発生します。

  magick koala.gif  -virtual-pixel Black  -interpolate NearestNeighbor \
          -filter point    -distort SRT 17    koala_rotated_srt.gif
[IM Output]
歪曲変換の別の議論については、Leptonica、アフィン実装、特に「点単位」方式に関する議論を参照してください。もう1つの方法である「シーケンシャル」は、基本的にIMが以前に回転およびシア歪曲演算子を実装していた方法です。
名前の由来は? 研究中に、この画像処理手法の明確な命名法がないことに気づきました。実際のアルゴリズム処理は「逆ピクセルマッピング」として知られていますが、数学的方程式の使用は「幾何変換」として知られています。歪みがさまざまな制御点の動きによって制御される場合、それはしばしば「画像ワーピング」または「ゴムシート」として知られています。特定の点を定義するプロセス、通常は2つ以上の画像間で同等の点を見つけることは、「画像レジストレーション」として知られています。画像は、個別に歪められるより小さく単純な単位に細分化することもできます。これは「グリッディング」(四角形)および「三角メッシング」(三角形)と呼ばれる手法を使用します。2つの画像からの色のブレンドを伴う小さな増分歪みを使用することにより、映画やミュージックビデオで見られるようなアニメーションの「画像モーフ」を生成できます。その場での数学的なルックアップではなく、事前に準備されたマッピング画像を使用する場合、ルックアップが相対的な変位である場合(50%グレーは変位またはルックアップ座標の変更がないことを意味します)、取得するものは「絶対歪曲マッピング」です。マッピングがルックアップの歪みではなく、色(シェーディング)をわずかに変更するだけの場合、関連性はあるが異なる「バンプサーフェスマッピング」を取得します。3Dモデリングや3Dコンピュータゲームでは、同じ手法が、平らな面と曲面に何らかの色のパターンを与えるためにも使用されます。これは、「テクスチャマッピング」として知られる手法です。これには、画像を単一のピクセルに近づくグリッドおよびメッシュに細分化することが含まれる場合があります。次に、「ポイントスプラッティング」と呼ばれる手法を使用して、数百万の単一点で定義されたオブジェクトを表示しますが、これは通常、順方向マッピングの歪みを使用して適用されます。上記のすべては非常に関連性が高く、最も基本的なのは、宛先の座標をソース画像(またはオブジェクト)にマッピングすることに基づいてピクセルの色をルックアップすることです。言い換えれば、宛先からソースへのマッピングです。どの用語を使用する必要がありますか...ご自由に選択してください。

ピクセルカラーのルックアップ

上記の逆ピクセルマッピング手法には、まだいくつかの問題があります。まず、宛先の固定された整数位置からピクセルをマッピングする場合、ソース画像内の非整数位置になる可能性があります。つまり、ソース画像の個々のピクセル間のどこかに位置する場所です。返す色を決定するために、補間と呼ばれるプロセスを使用して、周囲のピクセルの色を混合することにより、その実際の位置の最終的な色を決定します。補間設定は、歪んだ画像の一部が「引き伸ばされ」、単一のソースピクセルが宛先画像の広い領域に広がる場合も処理します。ただし、単純な補間方法では、反対のケースはうまく処理されません。そのため、以下で説明する別の手法が必要になります。たとえば、ここでもコアラを回転させますが、今回は「-interpolate メッシュ」設定を使用して、近くの4つのピクセルを混合し、ルックアップからより適切で正確な色を生成します。

  magick koala.gif  -virtual-pixel Black  -interpolate Mesh \
          -filter point    -distort SRT 17    koala_rotated_mesh.gif
[IM Output]
非整数のルックアップポイントを取り囲む最も近い隣接色の単純なマージを使用するだけで、歪んだ画像の見栄えを大幅に改善できることがわかります。しかし、他にも問題があります。たとえば、マッピングされた位置がソース画像を完全に「見逃した」場合、どうすればよいでしょうか。この場合、返す色は仮想ピクセル設定によって決定されます。この設定では、ソース画像の最も近いエッジなどの色を選択したり、ソース画像がプレーン全体に無限にタイル状(またはミラータイル状)になっていると仮定したり、白、黒、透明、またはユーザー定義の背景色などの特定の色を使用したりします。特定の宛先位置をマッピングするための数学的に有効な座標がない可能性もあります。たとえば、ピクセルは遠近法の「平面」の「空」を覗き込み(遠い地平線の表示を参照)、ソース画像が存在する「平面」さえ見ていません。この場合、仮想ピクセルは、N次元空間のソース画像平面に「ヒット」しないため、役に立たず、宛先ピクセルは完全に無効です!この場合、IMはピクセル色の現在の「-alpha set」設定を使用します。それが「ニアミス」である場合、IMは、その方法を知っていれば、この無効な色を画像平面の隣接色でアンチエイリアスします。これは遠近法の歪みに当てはまります。

スーパーサンプリング

補間は、単純な画像の歪みに適しています。ただし、ソース画像の一部がはるかに小さい領域に圧縮される場合、各宛先ピクセルは、実際にはソース画像のより広い領域のマージを必要とする可能性があります。ピクセルは実際には点ではなく、実際の画像の長方形の領域を表すことを覚えておいてください。つまり、場合によっては、ソース画像の広い領域を単一の宛先ピクセルに圧縮しようとする必要があります。これが起こると、単純なピクセルルックアップは、ソース画像内の単一の「点」(周囲のピクセル近傍を使用)での色のみをルックアップし、その単一のピクセルに圧縮する必要がある入力画像のすべての色をマージおよび結合しないため、失敗します。この結果、宛先ピクセルは、関連するすべての色の平均ではなく、ソース画像からの本質的にランダムな色で終わる可能性があります。これはそれ自体は悪いことではありませんが、ある領域のすべてのピクセルがこれを行うと、ランダムで孤立したピクセル、モアレ効果、エイリアスされた「階段状」効果のある画像が表示されます。細い線も、点線や破線のように見え始めたり(サンプル演算子の例を参照)、完全に消えてしまう可能性があります。これらの効果はすべて、まとめてエイリアシングアーティファクトとして知られています。これに対する1つの解決策は、宛先内の各ピクセルについて、より多くの色のルックアップをソース画像から行い、宛先画像内の各ピクセルに対してより正確な色を決定しようとすることです。最も単純な解決策は、一般的にスーパーサンプリングまたはオーバーサンプリングとして知られています。スーパーサンプリングに関するウィキペディアエントリを参照してください。各宛先ピクセルにマッピングされる領域にわたってソース画像からより多くのサンプルを取得することにより、そのピクセルの最終的な色は、そのポイントでの歪んだ画像のより正確な表現になります。作成するカラーサンプルが多いほど、最終的な色がより正確になり、よりスムーズでリアルな外観が生成されますが、歪みが遅くなります。この手法は、ソース画像が50%以上圧縮される領域で、宛先の一般的な外観を実際に改善するだけであることを覚えておいてください。歪みがソース画像を拡大したり、ほぼ同じスケールに保ったりする領域では、ソース画像の一回の補間ルックアップで、通常、1回のルックアップで良好な結果が得られます。画像をインプロードするワーピングの例(およびIM Examples全体にわたる他の多くの例)では、「スーパーサンプリング」の最も単純な方法について簡単に触れました。基本的に、出力画像のサイズを拡大する(またはこの場合、単に入力画像を拡大する)ことで、歪みを実行します。歪みが完了したら、画像を通常のサイズに戻して、生成されたすべての余分な「サンプル」をマージします。たとえば...

  magick -size 94x94 xc:red -bordercolor white -border 3 \
          -virtual-pixel tile                -implode 4 \
          implode_tiled_box.gif
  magick -size 94x94 xc:red -bordercolor white -border 3 \
          -virtual-pixel tile  -resize 400%  -implode 4 -resize 25% \
          implode_tiled_ss.gif
[IM Output]
ボックス画像の通常のインプロージョン
[IM Output]
スーパーサンプルされたインプロージョン
もちろん、入力画像を拡大する代わりに、より高品質(大きい)のソース画像から開始するか、前の処理ステップ中に生成することができます。利用可能な場合。これは、テキストを回転させる場合に特に役立ちます。テキストには、最終的な画像で高品質の外観を確保するために、均一に保持する必要がある非常に細かい詳細が含まれていることがよくあります。この例については、ポラロイド変換を参照してください。
IM v6.4.2-6以降、一般歪曲演算子は、拡大された出力画像を直接生成できます。この画像を縮小(またはサイズ変更)して、結果のピクセルをマージおよびスーパーサンプリングできます。歪曲スケール設定と次の例を参照してください。
これはスーパーサンプリング(「グリッド」法として知られる)の一つの方法に過ぎず、この方法には他にも多くのバリエーションがあります。最終的にはこれらの方法がImageMagickに直接実装されるかもしれませんが、今のところは、画像の単純な拡大と縮小が、追加のコーディングを必要とせずに非常にうまく機能します。最後に一つ注意点です。スーパーサンプリングは、最終画像の各ピクセルに使用されたサンプル数、つまり最終的なリサイズで使用されるスケーリング量によって制限されます。これは、歪んだ画像の最終的な「品質」を決定します。しかし、より大きなスケーリング係数を使用すると、歪んだ画像の生成は当然はるかに遅くなります。しかし、品質はさらに高くなりますが、それにも限界があります。極端な場合、スーパーサンプリングは、無限大を伴う画像歪み(インプロードされた画像の中心など)を処理できません。このような場合、エリアリサンプリング(下記参照)によって提供されるような、まったく異なる手法が必要です。要約すると、スーパーサンプリングは、回転、せん断、アフィン、単純な遠近法など、わずかな歪みしかない画像の見た目を改善できます。しかし、改善できる歪みの種類には限界があります。適応型スーパーサンプリング スーパーサンプリング技術はさらに拡張できます。各ピクセルに対して固定数のカラー参照を使用するのではなく、ソース画像内の参照間の距離、または低レベルのサンプリングから返された色がどれだけ近いかを確認して、特定のピクセルに対してより多くのサンプルを作成する必要があるかどうかをチェックします。つまり、スーパーサンプリングの量を、歪みの詳細を知らなくても、歪みのニーズに応じて調整できるようにすることができます。これは適応型スーパーサンプリングとして知られています。この技術は、特定の時点で結果として得られる画像がどれほど複雑であるかを判断することがほとんど不可能なレイトレーサーでは非常に一般的です。この場合、特定の位置周辺の「色の違い」を使用して、より多くのサンプルが必要な場合を判断することがよくあります。あるピクセルが隣接するピクセルと非常に異なる場合、その領域ではより多くのサンプルを使用して、おそらく3次元オブジェクトのエッジであるものを洗練します。IMは現時点では適応型スーパーサンプリングをサポートしていません。ただし、一般的な歪み演算子(下記参照)に代替のサンプリング方法を追加することは十分に可能です。コードの機能的な再配置が必要になるため、すぐに実装されるとは限りません。スーパーサンプリングの概要 スーパーサンプリングの難しさは、必要な「点サンプル」の数を決定すること、およびそれらのサンプルをサブピクセル境界でどのように配置するかを決定することにあります。また、どのような「重み付け」を適用すべきかも問題です。スーパーサンプリングに関するWikipediaのエントリを参照してください。

より良い歪みを得るためのエリアリサンプリング

スーパーサンプリング法の最良の代替手段の1つは、エリアリサンプリングです。より大きな画像を歪ませて、結果をリサイズによって平均化するのではなく、これは単に画像からより多くのサンプルを取得して平均化するだけですが、実際には、各特定の出力ピクセルを生成するために、ソース画像からいくつのピクセルをマージする必要があるかを(その時点での歪みの「スケール」に基づいて)正確に決定します。つまり、ソース画像内で、各出力ピクセルが表すおおよその「領域」を把握し、その領域内のすべてのピクセルをリサンプリングフィルターに従ってマージ(フィルタリング)します。実際、これは、ImageMagickのリサイズ演算子(実際には非常に特定のタイプの画像歪み)が、そのような優れた結果を生成するために行っていることです。ただし、リサイズの場合は、画像全体で各ピクセルに対してサンプリングする必要がある領域のスケールを1回計算するだけで済みます。サンプリングする必要がある領域はソース画像内の固定サイズの長方形(ウィンドウ)であるため、リサンプリングプロセスは簡単になり、歪みプロセスでショートカットが提供されます。歪んだ画像をエリアリサンプリングする場合、サンプルを取得するピクセル(ウィンドウ)の領域は、位置が変わるだけでなく、サイズも変化します。そのため、宛先の1つのピクセルは、いくつかのソース画像の色をマージするだけで済む場合や、1つの補間されたカラー参照(拡大時など)だけで済む場合があります。一方、宛先画像の別のピクセルは、正しい最終的な色を生成するために、非常に多数のピクセルをサンプリングする必要がある場合があります。無限大に近い場合、サンプリングプロセスの一部としてソース画像内のすべてのピクセルを含める必要がある場合さえあります。また、宛先ピクセルがソース画像で表す領域は、単純な正方形、円、または楕円ではなく、使用されている歪みに応じて、実際には高度に歪んだ形状である可能性があります。このような扱いにくい形状を計算して処理するには、非常に時間がかかる場合や、ほぼ不可能になる場合があります。[図]宛先ピクセルごとに色を計算するためにソース画像の楕円形の領域を使用する方法は、楕円重み付け平均(EWA)リサンプリングとして知られており、PDF研究論文「テクスチャマッピングと画像ワーピングの基礎」でPaul Heckbert(ほぼすべての画像リサイズアルゴリズムが派生した「zoom」プログラムも作成)によって概説されました。これは、新しい一般化された歪み演算子(下記参照)を定義するために使用されました。楕円は、アフィン歪みまたは遠近歪みのいずれかに最適な形状です。特に極端なスケール縮小に優れています(以下の例を参照)。また、他の歪みには完璧ではありませんが、円弧および極座標歪み(ただし、その逆は不可)、およびバレル歪みのような放射状歪みなど、他の多くの歪みにも一般的に適しています。(ただし、その逆は不可)ですが、デポラライズシェパーズ歪みなどの非線形歪みマッピングにはあまり適していないため、これらの歪みには使用されません。スーパーサンプルは、各「サンプル」が宛先に逆マッピングされるため、この形状の問題はありません。そのため、このような場合はより優れたサンプリング方法になります。ただし、前述のように、必要なすべてのピクセルをサンプリングしない場合や、ピクセルをサンプリングしすぎる場合があります。

エリアサンプリング vs スーパーサンプリング

これは、現在IMが提供している3つのサンプリング方法すべてを、極端な無限タイリングされた遠近画像に適用したものです。この歪みの詳細については、下記の遠い地平線の表示を参照してください。

  # input image:  special checkerboard with a gold outline.
  magick -size 90x90 pattern:checkerboard -normalize -fill none \
          -stroke gold -strokewidth 3 -draw 'rectangle 0,0 89,89' \
          -fill red        -draw 'color 20,20 floodfill' \
          -fill lime       -draw 'color 40,70 floodfill' \
          -fill dodgerblue -draw 'color 70,40 floodfill' \
          checks.png

  # Using Interpolated Lookup
  magick checks.png -filter point \
          -virtual-pixel tile -mattecolor DodgerBlue \
          -distort Perspective '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          horizon_tile_point.png

  # Using Grid Super Sampling
  magick checks.png  -filter point  -set option:distort:scale 10 \
          -virtual-pixel tile -mattecolor DodgerBlue \
          -distort Perspective '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          -scale 10%    horizon_tile_super.png

  # Using Area Resampling (default)
  magick checks.png       -virtual-pixel tile -mattecolor DodgerBlue \
          -distort Perspective '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          horizon_tile.png
[IM Output]
画像を確認
==> [IM Output]
補間済み
ルックアップ
[IM Output]
スーパーサンプリング
x10
[IM Output]
楕円重み付け領域
(EWA) リサンプリング
すべての画像はまったく同じ歪みですが、「リサンプリング」手法が異なるだけです。上記最後の画像は、一般化された歪み演算子のデフォルトのEWA設定を使用しており、ご覧のとおり、非常に高品質な結果が得られました。ただし、この画像の生成には4.6秒かかりました。これは、少し遅いものの(珍しい極端な状況が関与しているため)、それほど悪くはありません。最初の画像では、「-filter point」設定を使用して、デフォルトのEWAリサンプリングが無効になっています。これにより、各ピクセルに直接補間ルックアップを使用することが強制されます。そのため、この画像は比較的非常に高速(0.51秒)で生成されましたが、ご覧のとおり、「縮小」(ダウンサンプリング)が「距離」とともに増加するにつれて、ひどい結果が生じます。真ん中の画像は最初の画像と同じですが、歪んだ出力画像が10倍に拡大されてから、他の画像に一致するように縮小されています(グリッドリサンプリング)。つまり、各宛先ピクセルに対して100以上のピクセルがルックアップされ、平均化されて、結果をスーパーサンプルするようにしています。生成はかなり高速(1.2秒)であり、一般的に画像の品質を向上させますが、その改善には限界があります。上記の例で使用されている×10は非常に大きく、ほとんどのスーパーサンプリングで使用される典型的な3〜4倍のスケーリングをはるかに超えています。結果の最大の違いは、スーパーサンプリングは画像全体で均一に一般的な品質向上のみを行うことです。歪みが厳しくなるにつれて、壊れ始めます。その結果、中間にリサンプリングアーティファクトがはっきりと見え、特に地平線の直前にサーバーモアレ効果の線が現れます。モアレ効果は、ピクセルあたり10個のサンプルが画像のチェッカーボードパターンとほぼ一致するときに発生し、歪んだ色の効果を生み出します。一方、エリアリサンプリングは、前景ピクセルよりも(ほとんどの時間を費やす)地平線に近い問題のあるピクセルに集中しており、スーパーサンプリングよりも実際にはパフォーマンスが優れています。基本的に、上記は非常に極端な歪みであり、EWAルックアップにかかる時間はそれに見合ったものです。一般的に、単一の補間ルックアップよりもはるかに優れた結果を生成します。これは、すべての関連ピクセルを効率的に確認しながら、スーパーサンプリングのように、必要のない領域でサンプルを使用しすぎないためです。まとめると...単純な楕円(EWAリサンプリング)または長方形(リサイズ)を使用して「エリアリサンプリング」を実行すると、スケーリングされた、アフィン、または遠近歪みに関与するすべてのソースピクセルがマージされて、個々の宛先ピクセルの最終的な色が生成されるため、良好な結果が得られます。デポラライズ歪みなどの非常に非線形な歪みや、シェパーズ歪みやレイトレーシングのような不定歪みの場合、必要なすべてのソースピクセルをリサンプリングするのに正しい「領域」を見つけることは法外に高くなり、スーパーサンプリングが結果を改善するための最良の方法となります。しかし、ストレートタイリング、拡大、およびスケールされていない回転の場合、非常に高速な単一の「ポイント」補間ルックアップはおそらく必要なすべてであり、完全に操作なし(変更なし)の歪みを保証するために推奨される場合もあります(下記参照)。ただし、すべてのリサンプリング手法は、各ピクセルの色を決定するための単なる方法であることに注意してください。これは、宛先とソースの間(または可能な場合はその逆)の位置のマッピングに関する限り、実際には画像が歪む方法の一部ではありません。

一般化された歪み演算子

これらの例の生成、IMフォーラムでのその後の議論、および遠近法やその他の歪みをより簡単かつ高速に実行するためのユーザーからの複数のリクエストにより、IM v6.3.5-1に新しい演算子が追加され、さまざまな種類の画像歪みをより簡単に追加できるようになりました。この一般化された歪み演算子は「-distort」と呼ばれ、「-list Distort」を使用して、IMバージョンで利用できる歪み方法を確認できます。

  magick -list distort
-distort」演算子は、上記の歪み方法の1つと、カンマまたはスペースで区切られた浮動小数点値のリストで構成される2番目の文字列引数を受け取り、特定の歪み方法を制御するために使用されます。

  magick ... -distort  {method}  "{list_of_floating_point_values}" ...
与えられた浮動小数点数の値は、使用される歪曲手法に大きく依存しており、その意味も、選択された手法だけでなく、特定の手法に必要なコントロールポイントや属性の正確な数にも依存する可能性があります。これは特に、3つの独立した「アフィン」歪曲を1つの歪曲に組み合わせた「スケール-回転-平行移動」(または略して「SRT」)歪曲の場合に当てはまります。多くの歪曲手法は、コントロールポイント(画像座標で)のリストを受け取り、通常、これらは、歪曲が画像をどのように変更するかを制御する座標のペアとして与えられます。これらの座標のペアについては、後でコントロールポイントを使用した歪曲で詳しく説明します。

歪曲オプション、コントロール、設定

最適フィット +歪曲フラグ

デフォルトでは、「-distort」は通常、ソース画像を元の画像と同じサイズの画像に歪曲します。これには例外があり、「アーク」歪曲(極座標マッピングのバリアント)のように、入力ソース画像のサイズが画像の歪んだ形式ではあまり意味がない場合があります(詳細は以下のアーク歪曲を参照してください)。演算子のもう1つの形式である「+distort」(IM v6.3.5-7で追加)は、古い回転およびせん断演算子が行うのと同様に、歪んだ画像が入力画像全体を含むように(可能な場合)サイズを変更しようとします。ただし、この特定の「モード」の操作はさらに進んで、結果の画像の仮想キャンバスオフセット(ページ)も設定します。これにより、後で、適切なアルファ合成を使用して、コントロールポイントに従って正しい位置にこの画像を別の画像にレイヤーマージできます(基本的な例としてアフィンレイヤーを使用した3Dキューブを参照)。また、「+distort」は(歪曲手法に応じて)、ソース画像に存在する可能性のある既存の仮想キャンバスオフセットを考慮し、歪曲プロセスの一部として使用しようとします。個々の歪曲手法に関する注意を参照してください。したがって、一般歪曲演算子の「最適フィット」形式である「+distort」を使用する前に、「+repage」属性設定演算子を適切に使用して、そのオフセットをクリアまたは調整する必要がある場合があります。仮想キャンバスとオフセットが必要ない場合は、後で使用する必要がある場合もあります。キャンバス/ページジオメトリの削除も参照してください。通常の「-distort」は、歪曲自体に関してソース画像に存在するオフセットを無視しますが、そのオフセットを歪んだ画像にそのままコピーします。要約すると…結果を同じサイズの画像にマッピングするには、「-distort」を使用します。また、「+distort」を使用して、出力画像のサイズを自動的に設定しようとしますが、仮想キャンバスオフセット(ページ属性)も使用および生成します。この一般的なビューポート選択をオーバーライドし、結果に表示したい歪んだ画像のサイズと部分を正確に制御する場合は、歪曲ビューポート(下記)も参照してください。
注意…「+distort」によって生成される最適フィットビューポートは、ユーザーが通常期待するよりも2ピクセル大きくなります。その理由は、これらのピクセルには、領域リサンプリングフィルターから生じる半透明のピクセルが含まれており、これらのピクセルは、歪んだ画像の「エッジ結合」とオーバーレイを修正するために不可欠であるためです。技術的には、追加されるピクセル数は、リサンプリングフィルターのサポートの出力スケーリングに依存する必要があります。つまり、ピクセルの領域がリサンプリングフィルターによってどれだけ「広がる」可能性があるかです。ただし、各ピクセルのスケーリングは可変である可能性があるため、必要な追加ピクセルの数を正確に計算することは非常に難しい問題であり、通常は労力に見合うものではありません。したがって、追加される2ピクセルは「ごまかし」です。歪曲によってピクセルがより「広がる」原因となる画像の拡大はめったにないからです。また、ほとんどの標準リサンプリングフィルターのサポートは2単位であるため、2ピクセルを追加するのは妥当です。また、この追加は「固定」されているため、ユーザーは必要に応じて、単に(さまざまな方法で)画像サイズをトリミングするオプションを使用できます。画像の拡大を行うと、2ピクセルの「ごまかし」が明らかに小さくなりすぎます。ただし、それらは比較的まれな歪曲であり、これが問題になる場合は、ユーザーが独自のビューポート(下記参照)を定義できます。仮想キャンバス上の歪んだ画像の仮想オフセットは、これら2つの余分なピクセルを考慮するように調整されるため、歪んだ画像は単純な構成ではなくオーバーレイには正しいです。ただし、トリミングトリムではレイヤー化された画像の場所が保持されますが、シェーブ、およびチョップでは、このオフセットを基準にしてレイヤー画像がシフトすることに注意してください。

歪曲ピクセル色の決定

上記の逆ピクセルマッピングで説明したように、結果の画像の各点は、最初に、選択した歪曲手法に従って、出力画像内のそのピクセルの位置を、ソース画像内の同等の(逆歪曲)位置にマッピングすることによって決定されます。ただし、ピクセルの最終的な色を決定するのはそれほど簡単ではありません。これは、多数の要因の影響を受けるためです。

仮想ピクセルとタイル

歪曲マッピングされた点が、実際のソース画像にヒットせず、その横、または実際の画像から遠く離れた場所にヒットする可能性があります。この解決策は、ソース画像が現在の「-virtual-pixel」設定で定義された「無限」または「仮想」サーフェスで囲まれているふりをすることです。この設定の効果の詳細と例については、仮想ピクセルの例を参照してください。これは、ソース画像の歪んだ、または歪んでいないタイルパターンを生成するのに非常に役立ちます。このための手法は、仮想ピクセルセクション自体(歪んでいない)、および以下のアフィンタイリング遠い水平線の表示で示されています。

無効な歪みピクセル

宛先ピクセルの歪曲が仮想タイル画像にも「ヒット」しない場合があります!これは一般に、ある種の3次元空間歪曲手法を使用して画像を歪曲し、ピクセル「ベクトル」が画像が存在するソース平面にヒットしない場合に発生します。基本的に、歪曲の結果は数学的に「未定義」になります。その場合、色は「-mattecolor」設定から決定されます。たとえば、パースペクティブ歪曲で「空」が表示される場合(たとえば、遠い水平線の表示を参照)、ソース画像の場所を決定するための数学が「未定義」になりました(実際には定義されていますが、ユーザーの前方視点からは有効ではありません)。したがって、「-mattecolor」が「空」に出力されます。実際には、パースペクティブ歪曲アルゴリズムは、水平線に近いピクセルの「アンチエイリアシング」情報もいくつか含めることができていますが、そのような状況では一般的ではありません。

EWA リサンプリングとフィルター

宛先ピクセルがソース画像に「ヒット」する場所がわかったら、ソース画像内の「ヒット」ポイントに近いピクセルを使用して、宛先ピクセルを作成する色を決定する必要があります。通常、歪曲演算子は、領域リサンプリング法EWA(楕円加重平均)を使用して、ソース画像のより広い領域を平均化し、このピクセルの適切な色を計算します。「-filter」設定を使用して、EWAリサンプリングによってフィルターを変更できます。詳細については、リサンプリングフィルター、特に円筒フィルターを参照してください。もともと、円筒ガウスフィルターがEWAリサンプリングに使用されていました。これは、EWAリサンプリングの元の研究論文で定義されていたためです。しかし、これは非常にぼやけた結果を生み出す傾向がありますが、エイリアシング効果も生成しません。これは、そのバージョン(現在は修正済み)の前に極端なぼやけを引き起こした実装バグとともに、以前はデフォルトフィルターでした。ローレンシャン大学の数学教授であるニコラス・ロビドゥー氏との主要な議論の後、IM v6.6.5-0から、画像歪曲のデフォルトフィルターは、EWAリサンプリング用に特別に設計された、非常に「ミッチェルのような」三次フィルターである「ロビドゥー」フィルターに置き換えられました。このフィルターと他の円筒フィルターの詳細については、円筒フィルターを参照してください。ただし、基になるウィンドウ化されたSincフィルター関数は、より円形のウィンドウ化されたJincフィルター関数に置き換えられることに注意してください。したがって、「Lanczos」フィルターを選択すると、「Sincウィンドウ化されたSinc」フィルターではなく、「Jincウィンドウ化されたJinc」フィルターが返されます。詳細については、ウィンドウ化されたJinc円筒フィルターを参照してください。余談:「Sinc」関数は、グリッド上の半径方向の距離との関数相互作用によって、偶数の「ローブ」が使用されるたびに、フィルターの重みが自己相殺される(ゼロ重み合計)傾向があるため、円筒関数としては実際には使用できません。これにより、ピクセルレベルの市松模様「ハッシュ」パターンで使用すると、ほぼ無限の色を生成しようとする原因となります。基本的に、EWAは、リサイズ演算子のように、リサンプリングフィルターを使用します。そのため、特別なエキスパートフィルターオプションを使用してフィルターを変更することもできます。たとえば、「ガウス」およびガウスのようなフィルターのぼかしは、フィルターぼかし設定で制御できます。同様に、ローブサポート設定を使用して、「ランチョス」フィルターなどのウィンドウ化されたJincフィルターのサイズとパワーを制御できます。
EWAリサンプリングを自動的にオフにし、より直接的な補間ルックアップのみを使用する、多くの極端な歪曲手法があります。

たとえば、非極性化歪曲は、円形の弧の形状のリサンプリング領域を生成しますが、これは「楕円」の(EWA)リサンプリングにはあまり適していません。シェパードなどの他の歪曲では、「スケーリングファクター」の計算が非常に困難になりますが、歪曲演算子の将来の改善により、これが可能になる可能性があります)。

これらの歪み手法では、結果の画像圧縮(ダウンサンプリング)領域で深刻なエイリアシングアーチファクトの発生を防ぐために、スーパーサンプリング手法を使用することを推奨します。

リサンプリングの失敗

特殊な状況下では、EWAリサンプリング楕円が、加重平均を作成するために実際に「ヒット」する実際のピクセルを特定できない場合があります。基本的に、楕円があまりにも小さいか、非常に細いため、画像内のすべてのピクセルの間に完全に収まってしまうのです。そして、ピクセルの色がないと、その点での出力画像の色を生成できません。これは極端な状況であり、通常、高度なフィルター設定を操作しない限り、達成することは不可能です。しかし、万が一、ピクセルがヒットしない場合や、フィルターの重みがゼロになる場合、リサンプリングは失敗します。その場合、IMは、EWAフィルタリングをオフにした場合と同じように(次を参照)、単純な直接補間ルックアップにフォールバックします。これが起こっているかどうかを確認したい場合は、異常な背景色(「赤」など)の特別な背景補間を使用すると、このようなリサンプリングの失敗を強調表示できます。たとえば、ここでは、ボックスフィルターのサポートを小さく設定して、リサンプリング楕円を非常に小さくします。また、画像のどの部分が「ピクセルをヒットしたか」と、ヒットしなかった部分がわかるように、画像を大幅に拡大します。

  magick \( xc:red   xc:white xc:black +append \) \
          \( xc:blue  xc:lime  xc:white +append \) \
          \( xc:black xc:red   xc:blue  +append \) -append \
          -filter Box -define filter:support=0.4 \
          +distort SRT 30,0  bad_box_distort.png
[IM Output]
大幅に拡大された画像では、リサンプリング円は1つのピクセルのみをヒットするか(単色のエイリアスされた円を生成します)、円形のサンプリング領域がピクセルの間に完全に収まるため、どのピクセルとも一致できず、フィルターは、結果の画像に少なくともある程度有効な色を取得するために、補間された色のグラデーション(デフォルトでは双線形補間)にフォールバックします。これは同じ例ですが、補間方法を特別な(そして通常は役に立たない)背景補間(背景色を「グレー」に設定した場合、背景色を返すだけです)に置き換えたものです。

  magick \( xc:red   xc:white xc:black +append \) \
          \( xc:blue  xc:lime  xc:white +append \) \
          \( xc:black xc:red   xc:blue  +append \) -append \
          -filter Box -define filter:support=0.4 \
          -interpolate background -background Gray \
          +distort SRT 30,0   bad_box_distort_gray.png
[IM Output]
完全なカバレッジ(常に少なくとも1つのピクセルを見つける)を得るには、円筒形のリサンプリングフィルターは、少なくとも約0.707(sqrt(2)/ 2)(ボックスフィルターのデフォルト)の「サポート」が必要です。すべてのフィルターは、通常、この最小サポートサイズよりもはるかに大きいです。例については、円筒形フィルターのセクションを参照してください。
角にある小さな色のドットは、仮想ピクセルに対するリサンプリングの最適化(単色のVP領域をサンプリングするときに、コストのかかるEWAリサンプリングを中断する)によって発生します。これらは、"virtual-pixel"設定の選択によって消えるか、変化します。

通常、これは問題ではなく、ここでは歪みが元の画像よりわずかに大きい「最適フィットビューポート」を使用し、その結果、仮想ピクセルをサンプリングするエッジ周辺にいくつかの余分なピクセルが含まれているためにのみ表示されます。

補間された、または直接色のルックアップ

-filter point」を使用して、フィルタリング、したがってEWAリサンプリングをオフにすることができます。 これを行うと、ImageMagickは、カラールックアップを高速でシンプルなピクセル補間を使用するように切り替えます。つまり、「リサンプリング領域」なしで、ソース画像への「単一の点」参照のみを使用して色を検索します。結果のピクセルの色は、点に最も近い近傍のみに基づいて補間された色を使用します。
補間は一般に、深刻なエイリアシング効果を引き起こします
画像の縮小またはダウンサンプリングが行われる場合。
ただし、回転、タイリングなど、歪みが最小限の画像や、画像の拡大(拡大またはアップサンプリング)には非常に効果的です。スーパーサンプリング手法を補間と組み合わせて、強い圧縮、縮小、またはダウンサンプリングの領域で結果を改善することができます。補間されたエイリアシングを解決するためにスーパーサンプリングを使用する例については、偏光-偏光サイクル問題(EWAリサンプリングを使用できない歪み)を参照してください。

詳細な歪みサマリー

-verbose」を「-distort」を実行する前に設定すると(「+verbose」を使用して再度オフにします)、歪みは、指定された方法で指定された画像を歪ませるときに計算して使用するアルゴリズムと内部係数に関する情報を標準エラーチャネルに出力します。この情報を使用して、歪みがどのように機能し、適用されているかを確認して理解することができます。また、何がうまくいっていないかを把握するためのデバッグツールであり、新しい歪みを実装するプロセスの一部でもあります。

  magick koala.gif -verbose -distort SRT 0 +verbose  koala_noop.gif
[IM Output] ==>
[IM Text]
==> [IM Output]
注:結果の画像は、入力画像とほぼ同じですが、まったく同じではありません(次の「no-op歪み」を参照)。
詳細な出力では、指定された歪みの2つの代替歪み手法が詳細に示されています。1つは「アフィン投影」歪みであり、もう1つはDIY FXオペレーターの代替案で、出力画像(i,j)の特定のピクセルを入力画像(xx,yy)の補間ルックアップに正確にマッピングし、画像を変換する方法を詳しく説明します。複雑な数学(固有値)を使用して計算されるリサンプリング楕円を計算し、(i,j)ピクセルの色を決定するソース画像内のスケーリングされていない補間ルックアップポイントのみを計算します。どちらも歪み処理に関する情報を提供し、同じタイプの他の歪みで使用するための追加情報を抽出するために使用できます。この情報の使用に関するより複雑な例については、以下の透視内部および双線形内部を参照してください。また、画像歪みにFXコマンドを使用する例については、FX画像サイズ変更を参照してください。上記の追加および減算の余分な「0.5」は、「ピクセル座標」を「画像座標」に変換するために必要であり、画像歪みを正しく数学的に処理するために必要です。下の画像とピクセルの座標を参照してください。

No-Op 歪み

上記の例は、noop歪みを行う結果を示しています。つまり、実際には歪みを伴わずに(ピクセルの1対1マッピングのみ)、歪みを介して(何らかの二次効果のために)画像を処理します。EWAリサンプリングフィルターは、元の色とまったく同じ色を再現しませんが、その近傍で個々のピクセルをわずかにぼかします。これは、使用されている2次元フィルターによるものであり、色のぼかしは最小限ですが、決して排除することはできません。そのため、真の「noop」を行うには、EWAフィルタリングをオフにして、補間された、または直接カラー検索を使用する必要もあります(上記を参照)。

  magick koala.gif -filter point -distort SRT 0  koala_noop_perfect.gif
[IM Output]
ほとんどすべての補間設定では、正確に参照されている場合、通常、ソースピクセルの正確なコピーが抽出されます。ただし、念のため、歪みで生成される可能性のある浮動小数点エラーに関係なく、正確な色一致のみが返されるように、速度と保証のために最近傍補間を指定することもできます。

  magick koala.gif   -filter point  -interpolate nearest \
          -distort SRT 0  koala_noop_perfect_2.gif
[IM Output]
これは逆効果に思えるかもしれませんが、元の画像データを実際にサイズ変更せずに、画像の領域を拡大したり、画像(仮想ピクセルメソッドを使用)をタイル化したりするための非常に便利な方法になる可能性があります。例については、歪みを介した仮想ピクセルを使用したタイリングを参照してください。つまり、多画像仮想ピクセルタイリング、画像サイズの拡大またはトリミング、境界線の追加、または(整数またはサブピクセル量でさえ)平行移動など、二次効果のためにDistortオペレーターを使用します。これらは、画像が「歪んだ」必要はなく、何らかの「プログラムされた」方法で「変更」するだけで済みます。

ビューポート、歪みの参照場所

上記のように、「-distort」または「+distort」を使用すると、(仮想キャンバス設定を無視して)結果の「宛先画像」のサイズと位置が、ソース画像と同じになるか、歪んだソース画像の最適適合計算になるか(可能な場合)が変更されます。これら2つは基本的に、宛先画像が表示されている結果の「歪んだ空間」の部分を定義します。別の考え方としては、宛先画像が、歪んだ結果の画像を見ている「ウィンドウ」または歪んだ空間への「ビューポート」であるということです。「distort:viewport」設定は、これらの両方のデフォルトをオーバーライドし、歪んだ空間のどの部分を表示するかを直接指定できます...
-define distort:viewport=WxH+X+Y
-set option:distort:viewport WxH+X+Y
これらはIM v6.3.6-1で追加されました。歪んだ画像を拡大またはスケーリングするのではなく、歪んだ画像空間で表示される場所と領域(ビューポート)を指定するだけです。これは、特定のサイズの宛先画像を作成したり、歪んだ画像空間の特定の領域にビューをシフトしたりするために使用できます。無限のサイズ(仮想ピクセル定義)の歪んだ画像の「ビューポートトリミング」を使用することと非常によく似ています。たとえば、ここでは、出力結果を(noop歪みを使用して)コアラの頭だけにトリミングします。言い換えれば、元の歪んでいない画像の直接の「ビューポートトリミング」です。

  magick koala.gif  -define distort:viewport=44x44+15+0 \
          -filter point -distort SRT 0  +repage koala_viewport.gif
[IM Output]
ここでは、ビューを拡大して、歪んだ画像を取り囲む余分な空間を確認し、仮想ピクセルの設定が、元のソース画像を取り囲む無限の空間に及ぼす影響を示します。

  magick koala.gif  -define distort:viewport=125x125-25-25 \
          -filter point -distort SRT 0  +repage koala_viewport_2.gif
[IM Output]
この場合、範囲オペレーターを使用して画像を拡大するのに似ています。ただし、単に背景色で塗りつぶす代わりに、歪みは追加された領域を仮想ピクセル設定で塗りつぶします。この場合、デフォルトの「エッジ」仮想ピクセル設定を使用すると、元の画像の端に沿ったピクセルから複製されたピクセルの水平および垂直線になります。
仮想ピクセル設定をより適切に選択することもできます。たとえば、「背景」設定を使用すると、このnoop歪みが範囲オペレーターとほぼ同じように機能します。この画像の場合、「」仮想ピクセル設定の方が適切な選択肢でしょう。

  magick koala.gif  -define distort:viewport=125x125-25-25 \
          -virtual-pixel White -distort SRT 0  +repage koala_viewport_3.gif
[IM Output]
前の例の最後の「+repage」は、ビューポート設定を使用した場合に「-distort」が残したビューポートの仮想キャンバスオフセットを削除するために必要です。この情報は、この場合は必要ありません。歪んだ画像を重ねる場合など、他の場合では、そのオフセット情報が必要になります。
viewport オプションは、特に 'Tile' や 'Mirror' の仮想ピクセル設定と組み合わせて使用すると便利で、あらゆるサイズや異なるスタイルでタイル状の画像を生成できます。また、アフィンタイリング で例示されているように、歪ませてタイル状の画像を生成することもできます。

  magick koala.gif  -define distort:viewport=125x125-25-25 \
          -virtual-pixel Mirror -distort SRT 0  +repage koala_viewport_4.gif
[IM Output]

中央揃えの正方形トリミング

結果として得られる画像の 'viewport' を設定するために "-set" オプションを使用する場合、割り当てられた値に パーセントエスケープ を含めることができます。具体的には、数学的な計算を行うことができる FXパーセントエスケープ を含めることができます。これは、メモリ内の現在の画像のサイズなどの属性を利用して 'viewport' を計算し、最終的な結果の画像のサイズを指定できることを意味します。これはどういう意味でしょうか?つまり、'viewport' を使用して、通常は画像の1回以上のプリリード (またはより高度な API プログラミングインターフェース) と、それを実現するための外部計算を必要とする特定の種類の 切り抜き を生成できるということです。たとえば、元の画像のサイズや向きを事前に知らなくても、画像の「中央の正方形」を切り抜くことができます。これは複雑なので、読みやすく、コーディングしやすく、デバッグしやすくするために、viewport 式を変数に配置しましたが、実際には単なる定数 (固定) 式です。

  size='%[fx: w>h ? h : w ]'
  offset_x='%[fx: w>h ? (w-h)/2 : 0 ]'
  offset_y='%[fx: w>h ? 0 : (h-w)/2 ]'
  viewport="${size}x${size}+${offset_x}+${offset_y}"

  magick worldmap_sm.jpg  -set option:distort:viewport "$viewport" \
          -filter point -distort SRT 0  +repage   viewport_square.gif
[IM Output] ==> [IM Output]
結果として得られる画像は、画像のサイズに関係なく、あらゆる入力ソース画像から抽出できる最大の中心正方形です。歪み自体は実際には画像を歪ませるのではなく、viewport でカバーされている領域をコピーするだけです。すべての値が画像の向きに依存するため、「中央の正方形の切り抜き」を生成するには、4 つのすべての数値を計算する必要があることに注意してください。そのため、各式では 'w>h ? ... : ...' 形式の「画像の向き」テストを使用するため、結果の値は画像の向きによって異なります。
これは、画像の向きのテストの代わりに "min()" および "max()" 関数を使用した代替形式です。

  magick worldmap_sm.jpg  -set option:distort:viewport \
    "%[fx:min(w,h)]x%[fx:min(w,h)]+%[fx:max((w-h)/2,0)]+%[fx:max((h-w)/2,0)]" \
    -filter point -distort SRT 0  +repage  viewport_square_2.gif
[IM Output]
Fred Weinhaus の Tidbits ページより。同じことを行うための複数の画像処理技術を使用した手法が、サムネイル、正方形のパディングと切り抜き に示されています。

アスペクト比トリミング

この手法は、指定されたアスペクト比に合わせて画像を中央で切り抜くように拡張できます。また、フォーラムディスカッション アスペクト比に合わせて切り抜く も参照してください。

その他の viewport の例

結果に歪んだ空間のどの部分が表示されるかを制御するために viewport を使用する他の例については、以下の 画像の回転方法 も参照してください。

出力スケーリングとスーパーサンプリング

-define distort:scale=N
-set option:distort:scale N
IM v6.4.2-6 で、一般的な出力画像のスケーリングファクターとして追加されました。これにより、出力画像が指定された係数で拡大されるため、"-distort" は N2 個多くの歪んだルックアップ 'サンプル' を生成する必要があります。この数値は通常整数ですが、浮動小数点拡大係数にすることもできます。多くの歪みでは、結果として得られる歪んだ画像のサイズを「スケーリング」することもできますが、結果として得られる画像サイズは、そのスケーリングの影響を受けません (「ベストフィット」"+distort" が使用された場合を除く)。ただし、この 'scale' 設定は、結果として得られる画像の内容をまったく変更するのではなく、結果として得られる出力画像を拡大または縮小するだけです。たとえば、適切な 'viewport' と組み合わせて、特定のサイズに簡単に "-resize" できる画像を作成し、品質を損なうことなく歪んだ画像への制御された「ズーム」を生成できます。
たとえば、コアラの頭を「ズームイン」します。

  magick koala.gif -set option:distort:scale 2.5 \
          -set option:distort:viewport 44x44+15+0 \
          -distort SRT 0  +repage koala_zoom.gif
[IM Output]
viewport は 44x44 ピクセルであるように要求されましたが、実際の出力画像は 110x110 ピクセルにスケーリングされていることに注意してください。より一般的には、歪み操作の 'スーパーサンプリング' (上記参照) の簡単な手段として使用されます。この場合、整数の「スーパーサンプリング」スケールファクターが使用され、歪ませた後、画像は元のサイズに戻されて追加のサンプルが結合され、より高品質の結果が得られます。

  magick koala.gif -filter point -set option:distort:scale 10 \
          -distort SRT 0  -scale 10%   koala_super.gif
[IM Output]
また、画像品質を向上させるために「スーパーサンプリング」を使用する場合、「領域再サンプリング」は必要ないため (処理を遅くするだけです)、通常は "-filter point" オプションを使用してオフにします (前のセクションを参照)。

歪み手法の概要

スケール-回転-移動 (SRT) 歪み

最も単純な歪みの1つですが、おそらく最も汎用性の高いものの1つは、'SRT' または 'スケール-回転-移動' 歪みです。(SRT は単なる略語です) 上記の例では、画像に実際の歪みが適用されずに処理される「何もしない」歪みの例をすでに見てきました。ただし、フィルタリングはわずかなぼかしを引き起こす可能性があります。以下に、上記の「何もしない」歪みの結果を繰り返します...

  magick koala.gif    -distort SRT 0    koala_noop.gif
[IM Output] ==> [IM Output]
領域再サンプリング を使用した結果、画像はわずかにぼやけることに注意してください。ただし、IM 再サンプリングフィルタは、何もしない歪みに対してこのぼかしを最小限に抑えるように意図的に設計されており、通常の使用には必要です。

特別な目的で完璧な「何もしない」歪みを実行する場合は、EWA 再サンプリングをオフにしてください。つまり、上記の歪み演算子の前に「何もしない」フィルタ "-filter Point" を指定します。

'SRT' 歪みは、実際には単一の歪み手法における3つの個別の歪みであるため、「スケール-回転-移動' 歪みと呼ばれます。角度回転を除くすべての引数はオプションであり、これにより、最大7つの浮動小数点数で区切られた引数の数に応じて引数が非常に可変になります。
-distort SRT " 
                  Angle 
 "   -> 中央回転
        Scale     Angle 
  -> 中央スケールと回転
X,Y               Angle 
  -> 指定された座標を中心とした回転
X,Y     Scale     Angle 
  -> 座標を中心としたスケールと回転
X,Y ScaleX,ScaleY Angle 
  -> 同様
X,Y     Scale     Angle  NewX,NewY
  -> スケール、回転、および座標の移動
X,Y ScaleX,ScaleY Angle  NewX,NewY
  -> 同様
これは、選択した画像とオプションの制御点を取得します。制御点が指定されていない場合、入力ソース画像の正確な中心が使用されます。その点の周りで、歪みは順番に画像をスケーリング回転、そして選択した制御点を新しい位置に移動します。したがって、この歪みの名前が付けられています。上記の引数の順序は、実際に画像に適用される操作の順序を反映しています。変換の「中心」を原点に移動する X,Y 、画像を ScaleX,ScaleY 、画像を 角度 回転させ、次に NewX,NewY を使用して「中心」をこれらの座標に移動します。つまり、演算子は実際には単一の歪みとして同時に適用される4つの内部歪み演算を表しています。ただし、私たち人間にとっては3つの異なる歪みのみが関係しています。したがって、'コアラ' 画像を使用した簡単な例を見てみましょう... 引数が1つだけの場合は、画像の中心を中心とした単純な回転であり、基本的には以前の 回転演算子 と同様の結果を生成しますが、画像サイズの増加はありません。

  magick koala.gif  -background skyblue  -virtual-pixel background \
          -distort ScaleRotateTranslate -110 koala_srt_rotate.png
[IM Output]
デフォルトでは、出力画像にも入力画像のサイズが使用されるため、回転した画像がクリップされる可能性があります。また、画像に奇数または偶数のピクセル数があるかどうかに関係なく、完全に中央に配置されます。"+distort" の 'プラス' 形式と、結果として得られる仮想キャンバスオフセットのクリーンアップを使用して、通常の 回転演算子 と非常に類似したものを生成できます。

  magick koala.gif  -background skyblue  -virtual-pixel background \
          +distort ScaleRotateTranslate -110 +repage koala_srt_rotate2.png
[IM Output]
IM 6.7.3-4 から、回転演算子 は Distort SRT 歪みを使用するようになりました。これより前は、せん断演算 を使用していましたが、これは良い結果が得られませんでした。
透明な背景を使用して、30% 縮小しましょう。

  magick koala.gif  -alpha set -virtual-pixel transparent \
          +distort ScaleRotateTranslate '.7,-110' +repage koala_srt_scale.png
[IM Output]
次の引数のセットでは、画像の回転とスケーリングの中心となる '中心' を指定します。この点は、歪みを制御するために使用される画像の「制御点」または「ハンドル」と呼ばれます。この歪みに特定の点を使用しているため、「仮想オフセット」の複雑さを回避するために、「ベストフィット」モードを使用しないようにしましょう。たとえば、ソース画像の 28,24 にあるコアラの「鼻」の周りでコアラを回転およびスケーリングしてみましょう。さらに、X スケールと Y スケールを異なるように歪ませてみましょう。

  magick koala.gif  -background skyblue -virtual-pixel background \
          -distort ScaleRotateTranslate '28,24  .4,.8  -110' \
          koala_srt_center.png
[IM Output]
そして最後の例として、「鼻」を画像の底の近くに移動し、背景を一致する白色の背景に設定してみましょう。

  magick koala.gif  -virtual-pixel white \
          -distort ScaleRotateTranslate '28,24  .4,.8  -110  37.5,60' \
          koala_srt_trans.png
[IM Output]
最終位置も浮動小数点値であることに注意してください。実際、すべての引数は浮動小数点値にすることができ、歪みは適切に処理されます。スケール、回転、および移動の各操作は、その順序で実行されることを忘れないでください。ご覧のとおり、この歪みは非常に汎用性が高く、3つの異なる方法を使用して画像を順番に歪ませるものと考えることができますが、実際には3つの歪みをすべて同時に適用して、示された結果を生成しています。これにより、複数の個々の演算子を実行するよりも高速になり、一般的に最終結果が向上します。上記では、実際のソース画像の外側で参照される領域に使用される色を定義するための異なる 仮想ピクセル 設定の使用方法も示しています。補間 が回転に及ぼす影響については、回転された線とエッジの補間 を参照してください。この歪みは、特に画像を取得し、そのオブジェクトの動きと回転に基づいてアニメーションを生成するように設計されています。たとえば、ここでは、様式化された宇宙船を作成し、それを非常に大まかな方法でアニメーション化します。船は 20,75 (最初の「うずくまった」スケーリング用) にベースに配置され、移動と回転の通常の「ハンドル」は元の画像の 20,60 にある船の中心です。これらの点は、オブジェクトを単純な用語でアニメーション化できる制御点を表します。

  magick -size 80x80 xc:skyblue -fill yellow -stroke black \
          -draw 'path "M 15,75 20,45 25,75 Z  M 10,55 30,55" ' \
          spaceship.gif
  magick spaceship.gif \
          \( -clone 0  -distort SRT '20,75  1.0,0.6  0' \) \
          \( -clone 0  -distort SRT '20,60     1     0  20,49' \) \
          \( -clone 0  -distort SRT '20,60    0.9   20  27,35' \) \
          \( -clone 0  -distort SRT '20,60    0.8   45  40,23' \) \
          \( -clone 0  -distort SRT '20,60    0.5   70  55,15' \) \
          \( -clone 0  -distort SRT '20,60    0.3   75  72,11' \) \
          \( -clone 0  -distort SRT '20,60    0.1   80  100,8' \) \
          -set delay 50  -loop 0  spaceship_launch.gif
[IM Output] ==> [IM Output]
もちろん、これは静止画像をアニメーション化するために「SRT」歪みをどのように使用できるかの非常に大まかな例ですが、その概念は理解できるはずです。さらにフレームを追加したり、炎や煙などを加えることで、さらに改善することができます(投稿を歓迎します。最高の成果はあなたの名前とともにここに追加されます)。

画像の回転方法

画像はさまざまな方法で回転させることができます。しかし、単純な回転だけでは、あなたが探しているものではないかもしれません。サイズを変更せずに画像を回転させたい場合...

  magick rose: -virtual-pixel black -distort SRT '20'  rotate_normal.png
[IM Output]
または、回転した画像の一部が切り取られないように回転させたい場合...

  magick rose: -virtual-pixel black +distort SRT '20'  rotate_noclip.png
[IM Output]
ただし、通常は、画像の周囲の「黒い」仮想ピクセル(またはその他の非画像色)を表示したくありません。1つの解決策は、回転によって生じた実際の画像ピクセルのみを含むように、元の縦横比と同じ最大サイズの長方形に画像を(歪みビューポート設定を使用して)切り抜くことです。ただし、この長方形の計算は非常に難しく、ImageMagickフォーラムで、Math Help Forumで見つかったいくつかの数式を使用して、大いに議論されました。ここでは、回転を行い、可能な限り元の縦横比に近い内部切り抜きを行います。

  angle=20
  ratio=`magick rose: -format \
     "%[fx:aa=$angle*pi/180; min(w,h)/(w*abs(sin(aa))+h*abs(cos(aa)))]" \
     info:`
  crop="%[fx:floor(w*$ratio)]x%[fx:floor(h*$ratio)]"
  crop="$crop+%[fx:ceil((w-w*$ratio)/2)]+%[fx:ceil((h-h*$ratio)/2)]"
  magick rose: -set option:distort:viewport "$crop" \
          +distort SRT $angle +repage   rotate_internal.png
[IM Output]
これは複雑に見えますが、これは実際には、ビューポート設定、幅、高さ、および元の画像におけるオフセットを定義するために、4つの異なる値を計算する必要があるためです。別の方法としては、回転するだけでなく、画像をわずかに拡大して、元の画像の境界を「埋める」という方法もあります。

  angle=20
  magick rose: -distort SRT \
     "%[fx:aa=$angle*pi/180;(w*abs(sin(aa))+h*abs(cos(aa)))/min(w,h)], $angle" \
     rotate_correction.png
[IM Output]
この最後の方法は、写真のわずかな回転補正に理想的で、元の画像のサイズを維持できます。この方法がより単純である唯一の理由は、「スケール」値が1つだけ計算する必要があるため、'インライン'で実行できるためです。

制御点を使用した歪み

SRT」歪みメソッドは回転角度とスケールファクターを指定することで定義されますが、ほとんどの歪みはソース画像上の「点」を移動し、結果の画像内の新しい位置に移動することで定義されます。これは、「SRT」変換を定義する際の「中心」点の動きに少し似ています。これらの点はコントロールポイントと呼ばれ、通常は単一のコントロールポイントごとに4つの浮動小数点値(2組の座標)を与えることによって定義されます。したがって、多くの場合、歪みは複数の4つの値のセットで定義されます。例:
X1,Y1 I1,J1     X2,Y2 I2,J2     X3,Y3 I3,J3     X4,Y4 I4,J4 . . . .
ここで、ソース画像(仮想キャンバスに対する相対位置)のコントロールポイントXi,Xiは、歪んだ出力画像上のIi,Jiにマップされます。
ただし、Distort演算子は実際に出力座標をソース座標にマッピングしているため(逆ピクセルマッピングを参照)、上記を内部的に使用してI,J座標をX,Y座標にマップします。ただし、結果は同じになるはずです。考え方が違うだけです。
Distort演算子が最初に導入されたIMバージョン6.3.6-0より前では、コントロールポイントの座標順序は、すべてのソース座標の後にすべての出力座標が続くように定義されていました。しかし、これにより、どのソース座標と出力座標が互いに対応しているかを判断するのが非常に困難になり、歪みをさらに微調整するためにコントロールポイントを簡単に追加することができませんでした。
各コントロールポイントの移動が、カンマ(またはスペース)で区切られた浮動小数点値のリストにまとめて保持されるように、このように定義されています。また、将来の外部「コントロールポイントファイル」の使用も可能になります。コントロールポイントを使用した最も単純な歪みは「アフィン」歪みですが、後でわかるように、通常は3つのポイントで定義されますが、1つまたは2つのコントロールポイントの移動だけを使用することもできます。実際には、「SRT」は、「アフィン」歪みの2点または1点のサブセットにすぎません。たとえば、ここで、コアラ画像の「鼻」を「28,24」から新しい位置「45,40」(赤い矢印で示されています)に移動します。これにより、画像の位置が単純に「変換」されます。

  magick koala.gif  -virtual-pixel white \
          -distort Affine '28,24 45,40'   koala_one_point.png
[IM Output] ==> [IM Output]
2つのポイントを使用すると、「アフィン」歪みは、画像を変換するだけでなく、拡大縮小および回転もできます(「SRT」歪みのフルレンジ)。たとえば、ここで、コアラの「耳」(「30,11」と「48,29」からの赤い線)を、より大きな水平位置(「15,15」から「60,15」までの青い線)にマッピングします。これにより、コントロールポイントがこの新しい位置に移動するように、画像の拡大、回転、および変換が必要になります。

  magick koala.gif  -virtual-pixel white \
          -distort Affine '30,11 15,15  48,29 60,15'   koala_two_point.png
もちろん、「SRT」歪みは、上記の2点「アフィン」歪みを再現できた可能性がありますが、ここでは異なる方法で歪みを定義しました。達成しようとしていることによって、どの形式を使用すべきかはあなた次第です。

画像座標 vs ピクセル座標

一般的なケースでのコントロールポイントの使用は簡単ですが、歪んだ画像を別の画像や描画された構造と整列させる必要がある場合は、より困難になります。その理由は、IMのほとんどの演算子は座標を「ピクセル位置」の観点(たとえば、切り抜き描画などの場合)で処理するのに対し、歪みは数学的な「画像座標」で座標を処理するためです。覚えておく必要があるのは、画像内のピクセルは「点」ではなく、実際には1ピクセル単位の「領域」であるということです。つまり、10,10に配置されたピクセルは、10単位下/横から11単位下および横まで進む色の正方形領域を定義します。画像座標では、「ピクセル」の中心は実際には10.5,10.5にあります。つまり、画像の中心を特定の場所に移動するために画像を歪ませる場合は、0.5を追加する必要があります。したがって、画像の隅の「ピクセル」の位置を変更するには、0.5,0.5および-0.5,高さ-0.5にあるピクセルに関して画像を移動する必要があります。一方、画像の実際の「端」に関して画像の位置を変更するには、単に座標0.0,0.0および,高さを使用します。実際に位置付けたいものが、画像の「ピクセル」の中心なのか、それとも画像の「端」なのかを考える必要があります。または、特定の課題でそれが実際に重要であるかどうかを考える必要があります。歪んだ画像の上に他の要素を描画したい場合は、「ピクセル位置」で描画位置を指定する必要があることに注意してください。そして、そうです。「-draw」演算子は、浮動小数点値を使用して線、円、およびその他の形状を描画できます。同様に、オブジェクトのストローク幅および/または半径も浮動小数点値として指定できます。
[IM Output] ==> [IM Output]
1.0未満の描画ストローク幅はうまく機能しません(線の描画を参照)。また、領域塗りつぶしは、塗りつぶし領域の端に(ストローク幅の追加と一致して)0.5を追加します(描画塗りつぶし境界を参照)。これは、実際に使用されたストローク幅に関係なく実行されます。

詳細については、描画塗りつぶし境界を参照してください。これは私がバグと見なしているものです。

パーセントエスケープを使用した制御点

パーセントエスケープを歪み引数内で使用することもできます。たとえば、ある画像から画像属性を抽出し、それを使用して別の画像のサイズを変更して、最初の画像と一致させることができます。ここでは、「rose:」組み込み画像のサイズを取得し、「アフィン」歪みを使用して、より大きな「logo:」画像のサイズを同じサイズに変更します(縦横比は維持されません)。

   magick rose: -set option:rw %w -set option:rh %h +delete \
           logo: -alpha set -virtual-pixel transparent \
           +distort Affine '0,0 0,0     %w,0 %[rw],0   0,%h  0,%[rh]' \
           +repage logo_sized_as_rose.png
[IM Output]
歪みは仮想キャンバス上にわずかに大きな「レイヤー化された画像」(負のオフセットを含む)を生成することに注意してください。そのため、上記の例では「+repage」を含める必要がありました。歪みは、画像の正確または真の歪みを生成しており、正交的なリサイズされた画像ではないため、エッジもぼやけています。Distort演算子を使用して画像を、Resize演算子が実行するように正確にリサイズする、より高度な例については、歪み vs リサイズ、および以下の歪みリサイズメソッドを参照してください。パーセントエスケープを使用して、現在の画像リスト内の画像の位置に基づいて歪みを計算することもできます。この例は、アニメーション化された歪みに示されています。

制御点の最小二乗フィット

アフィン」歪みに3つ以上のコントロールポイントを指定した場合、または「パースペクティブ」または「バイリニア」歪みに4つ以上のポイントを指定した場合、ImageMagickは与えられたすべてのポイントに対して最小二乗平均を実行して、それらの歪みの「平均」表現を見つけます。これは、ある画像を別の画像と一致させようとしている場合(「画像登録」として知られる手法)、結果がより正確な歪みになるように、必要な最小ポイント数よりも多くのポイントを定義できることを意味します。もちろん、それらのポイントの1つ以上が他のポイントとうまく「フィット」しない場合、IMは与えられたすべてのコントロールポイント(不良なポイントを含む)を使用して最適なフィットを見つけようとするため、結果は「奇妙な」ポイントによって歪められます。状況によっては、「不良な座標ペア」を見つけて削除するためのチェックが必要になる場合があります。

ファイルからのコントロールポイント

歪みの数値(引数)のリストは、「-annotate」や「label:」などのテキストを入力できるのと同じように、「@filename」構文を使用してファイルから読み取ることもできます(テキスト引数でのエスケープ文字を参照)。たとえば、次のような歪みを指定できます...

  magick input.png  -distort Perspective '@file_of_coords.txt' output.png
ファイル名は、標準入力からファイルを読み取ることを意味する単なる「@-」にすることができます。ファイル自体は文字列として読み込まれ、関係する歪みに必要な座標(引数)のリストとして扱われます。数値はコンマまたは空白で区切ることができるため、座標ペアは、次の形式で1行に1組の座標としてきちんと順序付けることができます...
   X1   Y1   I1   J1
   X2   Y2   I2   J2
   X3   Y3   I3   J3
   X4   Y4   I4   J4
   ....
最小二乗フィッティングにより、画像登録の使用が非常に実用的になります。ファイルは1行あたり4つの数値のリストにすぎないため、「cut」、「paste」、「column」などの他のテキスト処理スクリプトツールや、「sed」、「awk」、「perl」などのより高度なテキスト処理スクリプトツールを使用して、座標を操作できます。座標および歪み引数ファイルの使用は、「シェパード」歪み、および計画されている今後の「Grid」および「Mesh」歪みなど、より高度な歪みでより重要になります。数百の座標ペアが含まれる場合があります。

アフィン(3点)歪みメソッド

アフィン歪み

上記の「SRT」歪みと、「アフィン」歪みの1点および2点の形式は、実際には「アフィン」歪みの完全な3点形式の単純化です。実際、「-verbose」出力の「SRT」歪みを調べると(例については、詳細歪み設定を参照)、内部的には実際には「AffineProjection」歪みであることがわかります(下記参照)。上記のメソッドが完全には処理できない歪み効果は、シア演算子が提供するような「シア」に似たものでした。そのためには、3点アフィン歪みを使用する必要があります。これを、最初の座標マッピングを「原点」とし、他の2つの座標マッピングをその原点からのベクトルと想像することで、3点歪みとして考えることができます。たとえば、ここでテキストを描画し、そのテキストに対する3つのコントロールポイントを定義するために、赤と青の「ベクトル」を重ねます。ここで、(画像座標として)それらの2つの線の座標を移動することで、テキスト画像を変換、回転、拡大縮小、およびシアして、それらの線の新しい位置に合わせることができます。

  magick -background lightblue -fill Gray -font Candice \
      -size 100x100 -gravity center label:Affine\! \
      -draw 'fill blue stroke blue path "M 3,60 32,60 M 27,58 27,62 32,60 Z"' \
      -draw 'fill red  stroke red  path "M 3,60  3,30 M  1,35  5,35  3,30 Z"' \
      label_axis.png
  magick label_axis.png \
          -distort Affine ' 3.5,60.5   3.5,60.5
                           32.5,60.5  32.5,60.5
                            3.5,30.5  33.5,20.5' label_axis_distort_shear.png
  magick label_axis.png \
          -distort Affine ' 3.5,60.5   3.5,60.5
                           32.5,60.5  27.5,85.5
                            3.5,30.5  27.5,35.5' label_axis_distort_rotate.png
  magick label_axis.png \
          -distort Affine ' 3.5,60.5  30.5,50.5
                           32.5,60.5  60.5,80.5
                            3.5,30.5  30.5,5.5' label_axis_distort_affine.png
[IM Output] ==> [IM Output] [IM Output] [IM Output]
最初の例では、3番目の座標(垂直な赤い線)のみが変更され、画像がせん断され、Y軸に沿って引き伸ばされました。もちろん、Y軸に限定する必要はありません。後の例では、回転や平行移動など、画像にさらに根本的な変更を加えています。もちろん、テキスト注釈演算子も、角度を変更するだけで、同じように実際のテキストを歪めることができます。この演算子は、テキストを特定の方向に拡大または縮小することはありません。つまり、「ベクトル」を回転させることはできますが、長くしたり短くしたりすることはできません。例の表については、注釈引数の使用法を参照してください。アフィン歪みは、描画されたテキストだけでなく、あらゆる画像に対してこの種の歪みを実行できます。3つ未満またはそれ以上の座標ペアを使用したアフィン。1つまたは2つの制御点ペアのみが提供されている場合、IMは、それらの少ない点の動きに合わせて、より限定された形のアフィン歪みを使用します。たとえば、座標ペアが1つしかない場合は、画像のスケールなしの平行移動に限定されます。2つの点の場合、「スケール-回転-平行移動」歪み(せん断なし)に限定されます。例については、制御点を使用した歪みに関する前の説明を参照してください。3つ以上の制御点が「アフィン」歪みに与えられた場合、IMは最小二乗法フィッティングを使用して、与えられたすべての座標ペアに一致する最適な「3点」アフィン歪みを検索します。つまり、ソース画像の制御点は、宛先画像の制御点に正確にマップされない場合がありますが、与えられたすべての点の最適な「平均」がマップされます。たとえば、ドキュメントのスキャンがある場合、ドキュメントの4つの角すべてを特定してマッピングし、アフィン歪みでドキュメントの回転とスケーリングを修正できます。この方法では、3点ではなく4点に基づいて、より優れた「平均」適合を得ることができます。より多くの座標を使用すると、より優れた、より正確な歪みが生成される可能性があることに注意してください。ただし、1つの座標ペアが非常に悪い場合、最小二乗法による適合では、まったく良い適合が得られない可能性があります。「悪い座標ペア」を排除するためのいくつかのチェックが必要になる場合があります。将来の機能:IMにコードを追加して、ユーザーが削除する必要がある「悪い点」を判断するのに役立つように、入力座標ペアのそれぞれが他の座標ペアに対してどれだけ「正確」であるかを報告します。

アフィン射影歪み

すでに述べたように、「SRT」歪みのさまざまな引数と、「アフィン」歪みの制御点は、数学的に「アフィン射影」の「係数」を表す6つの特別な数値に変換されます。アフィン射影のこれらの数値は、ソース画像の点を宛先画像に順方向マッピングするために使用される係数です。つまり、ソース画像x,yを宛先画像i,jにマッピングするために使用される数学的な値です。6つの浮動小数点引数は、与えられる順序で次のとおりです...
sx, rx, ry, sy, tx, ty
これらは歪み式を形成します。
Xd = sx*Xs + ry*Ys + tx   ,       Yd = rx*Xs + sy*Ys + ty
ここで、"Xs,Ys"はソース画像の座標であり、"Xd,Yd"は宛先画像の座標です。内部的に、ImageMagickのDistortは、上記の式を反転させて、適切なピクセルマッピングを実行し、"Xd,Yd"座標を、ソース画像の"Xs,Ys"で色をルックアップするようにマッピングします。さまざまなアフィン射影行列の値が画像にどのように影響するかについては、アフィン行列変換サブページを参照してください。これらの係数が事前に計算されている場合(たとえば、歪みの詳細出力から抽出したり、他の形式の入力引数から他の方法を使用して自分で計算したりした場合)、それらをIMに直接提供して画像を歪ませることができます。たとえば、ここでは、制御点の動きではなく、角度を使用して係数を計算することにより、画像を「せん断」します。

   angle=-20
   tan=`magick xc: -format "%[fx:tan( $angle *pi/180)]" info:`
   magick koala.gif -alpha set -virtual-pixel Transparent \
           +distort AffineProjection "1,$tan,0,1,0,0" +repage \
           koala_affine_proj.png
[IM Output]
ImageMagickでこの歪みを実行する従来の方法は、「-affine」と「-transform」の操作ペアを使用することでした。ただし、IM v6.4.2-8以降、これは、Distort演算子の「プラス」または「最適適合」形式を使用する「AffineProjection」への簡単な呼び出しにすぎません。詳細については、アフィン行列変換サブページを参照してください。

アフィン歪みの例

アフィンタイリング

これまで見てきた上記のアフィンに似た3つの歪み方法はすべて、歪んだ画像に基づいてさまざまなタイルパターンを生成する興味深い方法も提供します。

  magick checks.png    -alpha set    -virtual-pixel tile \
          -distort  ScaleRotateTranslate  '20,20  .5  30' \
          checks_srt_tile.png
  magick checks.png    -alpha set    -virtual-pixel tile \
          -distort  Affine  '0,0 10,10   0,89 10,50   89,0 50,0' \
          checks_affine_tile.png
  magick checks.png    -alpha set    -virtual-pixel tile \
          -distort  AffineProjection  '0.9,0.3,-0.2,0.7,20,15' \
          checks_amatrix_tile.png
[IM Output] ==> [IM Output] [IM Output] [IM Output]
この方法での歪みマッピングの使用は、実際には3Dグラフィックライブラリおよびゲームでの「テクスチャマッピング」の仕組みです。唯一の違いは、サーフェスの3次元座標を2次元画像にマッピングすることです。Distort Viewportが適切な「no-op」歪み("-distort SRT 0")であっても、アニメーション化されたグリッタータイルなど、画像シーケンス全体をタイル状に配置する便利な方法を提供します。

  magick glitter_blue.gif -virtual-pixel tile \
          -filter point -set option:distort:viewport 100x100 -distort SRT 0 \
          glitter_blue_tiled.gif
[IM Output] ==> [IM Output]
また、EWAリサンプリングをオフにするために「-filter point」を使用しました。これにより、操作が高速化されるとともに、ソース画像のピクセルの完全な(非サンプリング)コピーが保証されます。Distort Viewportは、オフセットを指定して、結果の画像でタイル状の画像を「ロール」することもできます。

アフィンレイヤリングを使用した3Dキューブ

制御点を持つ「アフィン」歪みは、3つの画像から、正投影および等角投影キューブ(定義については、Wikipediaの正投影および等角投影を参照)を生成するのに理想的です。必要なのは、宛先画像上の4つの制御点を特定することだけです。画像レイヤリング技術を使用するため、ポイントは負の値を持つこともでき、IMは、生成された歪んだ画像に合わせて最終的な画像サイズを調整できます。この例では、キューブの中心の制御点を「0,0」、その中心点の周りに等間隔に配置された3つの点を「-87,-50」、「87,-50」、および「0,100」として選択します。次に、必要なのは、3つの(できれば正方形の)画像の適切なコーナーをこれらの制御点にマッピングすることだけです。

  magick \
     \( lena_orig.png -alpha set -virtual-pixel transparent \
        +distort Affine '0,512 0,0   0,0 -87,-50  512,512 87,-50' \) \
     \( mandrill_orig.png -alpha set -virtual-pixel transparent \
        +distort Affine '512,0 0,0   0,0 -87,-50  512,512 0,100' \) \
     \( pagoda_sm.jpg -alpha set -virtual-pixel transparent \
        +distort Affine '  0,0 0,0   0,320 0,100    320,0 87,-50' \) \
     \
     -background none -compose plus -layers merge +repage \
     -bordercolor black -compose over -border 5x2     isometric_cube.png
[IM Output]
画像を歪ませるときに、画像の実際の端の座標を使用したことに注意してください。これは、数学的には、画像が正確にフィットする必要があることを意味します。また、単純に画像を(デフォルトのオーバーアルファ合成を使用して)「合成」しなかったことに注意してください。そうすると、画像間にわずかに透明な「ギャップ」ができます。正しい方法(示されているとおり)は、プラスアルファ合成を使用して、「エッジ接続」されたピースを結合することです。これにより、透明なギャップのない完璧な結合が得られます。詳細については、2つのマスクされた画像の整列を参照してください。その後、追加の境界線を追加し、すべての透明度を削除しました。これは必須ではなく、任意の背景(または「none」)を簡単に使用できますが、そうすることで画像に「ギャップ」がある場合に強調表示されます。
[IM Output] 右に示されているのは、画像内のそのような結合の1つの拡大図であり、結合に沿って「黒塗り」のギャップがないことを示しています。 「-distort」を使用せずに等角投影キューブを作成する別の方法については、せん断を使用した等角投影キューブで説明しています。ただし、この手法では、サブピクセル座標を使用することはできません(上記では使用していませんが、使用できた可能性があります)。代わりに、整数ピクセル(整数)座標を使用して画像を配置することに限定されます。

アフィンせん断を使用した3Dシャドウ

上記で使用したのと同じレイヤリング方法を使用して、奇妙な形状のクールな3次元シャドウを生成することもできます。これにより、直立しているあらゆる「平ら」な形状の影が追加されます。たとえば、平らなベースを持つ形状を作成して、直立できるようにしましょう。

  magick -background None -virtual-pixel Transparent -fill DodgerBlue \
          -pointsize 72 -font Ravie  label:A   -trim +repage \
          -gravity South -chop 0x5  standing_shape.png
[IM Output]
「形状」には平らなベースがあり、これは画像の最後の行でもあります。これは、その行に沿って形状を歪ませ、影がその行だけで直立している形状に接続するようにするため重要です。この「直立した形状」から3Dシャドウを生成するコマンドを次に示します。

  magick standing_shape.png   -flip +distort SRT '0,0 1,-1 0' \
          \( +clone -background Black -shadow 60x5+0+0 \
             -virtual-pixel Transparent \
             +distort Affine '0,0 0,0  100,0 100,0  0,100 100,50' \
          \) +swap -background white -layers merge \
          -fuzz 2% -trim +repage   standing_shadow.jpg
[IM Output]
上記では、表示された結果を実現するために、かなりの数のステップを実行しています。ただし、最も難しいのは最初の行です。これにより、画像が反転し、再び「歪み反転」が行われます。この結果、一番下の行が仮想キャンバスでY=0の値を持つように配置されます。つまり、画像全体に負のオフセットが与えられ、一番下の行が仮想キャンバスの原点を通過するように配置されました。この「トリック」を実行することで、抽出された「影」に対して非常に単純な「アフィンせん断」を使用して歪ませることができます。したがって、影を歪ませるために形状画像のサイズを知る必要はありませんが、すべてが元の画像の底(Y=0)行に沿って同期されたままになるため、すべてを「整列」させることができます。「アフィンせん断」の最後の座標(「100,50」)を調整するだけで、影が落ちる方向とその長さを調整できます。最初の2つの「座標ペア」は、影を一番下の行に沿って元の画像に「ロック」するため、変更しないでください。ただし、最後のステップまで、すべての画像には負の仮想キャンバスオフセットが含まれるため、中間処理画像を表示または保存する場合は注意が必要です。この影の効果に関する唯一の問題は、それが「普遍的なぼかし」であるということです。つまり、影は現実的ではありません。実際には、影は「直立した形状」に結合する場所ではシャープであり、影が遠くなるほどぼやけるはずです。ただし、これは可変ぼかしマッピングを使用して実行できます。たとえば、距離ぼかし影フォントで使用されているようなものです。

遠近感圧縮を使用した3Dシャドウ

これは影に可変ぼかしを追加する別の方法ですが、実際にはお勧めしません。実装は非常に簡単です。この例は、可変ぼかしマッピングがImageMagickに追加される前に開発されました。基本的に、まず遠近感歪み(以下で詳しく見ていきます)を使用して最初の影の形状を歪ませ、影の「遠い部分」を大幅に圧縮してぼかし、次に上記で使用した最終的な「アフィンせん断」位置に歪ませて、その圧縮を拡張します。

  magick standing_shape.png   -flip +distort SRT '0,0 1,-1 0' \
          \( +clone   -virtual-pixel Transparent -mattecolor None \
             +distort Perspective \
                '0,0 0,0  100,0 100,0   0,-100 45,-100   100,-100 60,-100' \
             -fuzz 2% -trim   -background Black -shadow 60x3+0+0 \
             +distort Perspective \
                '0,0 0,0  100,0 100,0   45,-100 -100,-50   60,-100 0,-50' \
          \) +swap -background white -layers merge \
          -fuzz 2% -trim +repage     standing_shadow_var.jpg
[IM Output]
これは、オリジナルの3Dシャドウイングの例とほぼ同じですが、いくつかの追加ステップがあります。元の形状はまず台形に変形され、次のステップを高速化するために余分なスペースがトリミングされます。次に、変形された形状からぼやけた影を抽出します。影の画像が変形された画像から作成されたら、同じ制御点を使用して影の画像を元に戻し、アフィンせん断としてその位置に移動します。重要なのは、影のぼかしが変形された画像に対して行われ、その後、元に戻される(そして、この場合は同時にアフィンせん断される)ということです。その結果、ぼかしも歪んで拡大し、影の上部をより多くぼかし、ベースラインに沿ってはるかに少なくぼかします。遠近感のあるぼかしの結果として、可変ぼかしが得られ、地面のベースラインから約100ピクセル離れたところでピークになるはずです。初期の遠近感ぼかし制御点によって定義されます。

歪みを使用した画像のリサイズ

歪みリサイズは、多くの点で非常に似ています。どちらも画像歪み演算子であり、どちらも逆ピクセルマッピングを使用して結果の画像を作成します。また、どちらも色の決定のために、「-filter」設定とそのエキスパートコントロールを利用していますが、その方法は大きく異なります。リサイズは簡略化された(そしてより一般的な)画像歪み操作であり、多くの最適化を可能にします。直交配置されており、リサイズで2パス直交画像フィルタリングメソッドを使用できます。つまり、まず1つの次元でサイズを変更し、次にもう一方の次元でサイズを変更し、中間の一時画像を使用します。また、スケーリング係数は宛先画像全体で一定であり、エッジがピクセル全体(整数)次元に揃えられているため、アルゴリズムは処理と使用するフィルターのキャッシュ要件を大幅に簡略化できます。これらの制限により、さまざまな最適化が可能になり、歪みが行う必要のある作業と比較して非常に高速になります。歪みは画像のリサイズもできますが、元の画像から結果の新しい画像に直接変換するシングルパスで行います。エッジを整数のピクセル位置に揃える必要がなく、各ピクセル位置を回転およびスケーリングできます。言い換えれば、最適化の余地が少ないため、最終結果の各ピクセルに対して非常に多くの追加処理を行う必要がある、はるかに一般的な演算子です。歪みリサイズと同じ画像を生成するには、まったく同じ制限に従い、いくつかの複雑な画像処理トリックを使用する必要があります。これについては、IMフォーラムの正しいリサイズ(歪みを使用)で議論され、アフィン歪み法の使用に基づく、同等の歪みリサイズ手法が得られました。
結果の「リサイズ」歪みメソッドは、ImageMagickバージョン6.6.9-2に追加されました。この歪みのコマンドラインインターフェース(CLI)バージョンは、ジオメトリ引数リサイズとまったく同じように受け入れて処理します。これには、2つの次元のスケーリング係数のわずかな違いも含まれ、直接のリサイズ代替手段となります。

  magick logo:  -distort Resize 150x  logo_resized.png
[IM Output]
リサイズ」歪みメソッドへの他のAPIインターフェースは、引数として2つの数値のみを受け入れ、それらは結果の画像の最終的な整数サイズとして扱われます。現時点では、最終的な画像サイズを変更するさまざまなリサイズ制御フラグを含む実際のジオメトリ引数を受け入れません。つまり、パーセンテージ、拡大/縮小のみのリサイズ、さらにはアスペクト比の維持などのフラグは使用できません。

この特別な画像歪みメソッドのそのようなサポートを追加するのは、これらのAPIのメンテナーに任されています。
上記の歪みリサイズと通常のリサイズ演算子の実際の違いは、歪みバージョンが、各ピクセルの最終的な色を決定するために、はるかに遅いシングルパスの円筒形(楕円形)フィルターを使用していることです。言い換えれば、2パス直交フィルター(リサイズ)と、1パスだが2次元の円筒形フィルター(歪みリサイズ)を直接比較できます。そのような比較の1つについては、歪み対リサイズを参照してください。

歪みリサイズの内部構造

以下は、上記の歪みリサイズが内部で実行した同等の操作です。

  magick logo:  -alpha set -virtual-pixel transparent \
          +distort Affine '0,0 0,0   %w,0 150,0   0,%h 0,113' \
          -alpha off  -crop 150x113+0+0 +repage   distort_resize.png
(2か所で使用されている)値「150」と「113」は、最も近い整数に対する最終画像の目的のサイズです。これは、最終的な整数サイズの制限を守りながら、画像のアスペクト比を最適に維持するように計算されました。それらは通常、個別のAPI関数を使用して、ImageMagickによって指定されたリサイズジオメトリ引数から計算されます。次に、透明度と透明な仮想ピクセルを有効にして、外部の「仮想ピクセル」が最終的なピクセル色の計算に関与しないようにします。歪みが完了すると、透明度が再び削除(オフ)され、歪みによって追加された「バッファ」ピクセルは、画像クロップを使用して削除されます。透明なピクセルの使用のため、上記のコマンドは、上記の「logo:」組み込み画像例のような透明度を含まない画像に対してのみ正しく機能します。これは、仮想ピクセルの効果を、画像内の可能な既存の透明度から分離するために必要な、はるかに複雑なバージョンです。

  magick logo: -alpha set -virtual-pixel transparent \
          \( +clone -alpha extract -alpha opaque \) \
          +distort Affine '0,0 0,0   %w,0 150,0   0,%h 0,113' \
          -alpha off -crop 150x113+0+0 +repage \
          -compose CopyOpacity -composite      distort_resize_trans.png
これは、2つの歪みを実行します。最初に画像を歪ませ、次にアルファ(透明度)チャネルを別々に歪ませます。その場合、透明度を使用して仮想ピクセルの影響を削除します。その結果、元の画像に透明度がない場合よりも少なくとも2倍遅くなります。これらの手法は両方とも、歪みリサイズメソッドによって内部的に実装されています。そのため、この「メソッド」は実際には「アフィン」歪みである実際の歪みメソッドではなく、ユーザーにとって便利な「マクロ」です。

4点歪みメソッド

遠近感歪み

おそらく最も一般的に要求される歪みのタイプは、高速な遠近感歪み操作です。これは4点歪みであるため、少なくとも4組の制御点ペア、または16個の浮動小数点値を必要とします。たとえば、ここに建物の画像があります。この画像から、手動で4つの点(赤)の位置を発見しました。また、最終画像でそれらの点が変換される最終的な位置(青)も定義して、建物の面を「まっすぐにする」または「修正する」ようにしました。

  magick building.jpg \
          -draw 'fill none stroke red polygon 7,40 4,124, 85,122, 85,2' \
          building_before.jpg
  magick building.jpg \
          -draw 'fill none stroke blue polygon 4,30 4,123, 100,123, 100,30' \
          building_after.jpg
[IM Output] ==> [IM Output] [IM Output]
実際の画像歪みを行うには、それらの座標を「-distort」の「perspective」メソッドにフィードするだけです。

  magick building.jpg -alpha set -virtual-pixel transparent \
         -distort Perspective \
              '7,40 4,30   4,124 4,123   85,122 100,123   85,2 100,30' \
          building_pers.png
[IM Output] ==> [IM Output]
歪みがソース画像のピクセルデータを「見逃した」右上隅の空白領域に注目してください。このような状況でIMが行うことは、「-virtual-pixel」設定によって制御されます(仮想ピクセルを参照)。あまり目立たないのは、元の画像の左端のごく一部も同じ理由で「失われる」ことです。興味深いことに、各マッピングペアの座標を交換して歪みを反転させてみましょう。これにより、歪みによって画像のどの程度が劣化しているかを確認できます。

  magick building_pers.png  -alpha set -virtual-pixel transparent \
         -distort Perspective \
              '4,30 7,40   4,123 4,124   100,123 85,122   100,30 85,2' \
          building_pers_rev.png
[IM Output] ==> [IM Output] ==> [IM Output]
悪くない。多くの「ぼやけ」がありますが、それは仕方ありません。「ぼやけ」は、最も圧縮された画像の右側でより悪化することに注意してください。すべての歪みはこの圧縮の問題に悩まされているため、すでに歪んだ画像を歪ませるのではなく、常に元の画像から歪ませるようにする必要があります。次に、上で作成した特別なチェッカーボードテスト画像を使用して、この変換を使用し、歪ませてから歪みを反転させる別の例を示します。

  magick checks.png        -alpha set    -virtual-pixel transparent \
          -distort Perspective '0,0,0,0  0,90,0,90  90,0,90,25  90,90,90,65' \
          checks_pers.png
  magick checks_pers.png   -alpha set    -virtual-pixel transparent \
          -distort Perspective '0,0,0,0  0,90,0,90  90,25,90,0  90,65,90,90' \
          checks_pers_rev.png
[IM Output] ==> [IM Output] ==> [IM Output]
画像の圧縮によって引き起こされるわずかなぼやけが見られますが、画像は基本的に復元されます。実際に起こることは、IMが、この歪みを実行するために、与えられたすべての制御点ペアを使用して「遠近法投影」(次を参照)の適切な係数を計算することです。 詳細設定を含めると、係数と、IMがこの歪みを実行するために内部的に使用しているDIY FX同等の両方を確認できます。制御点ペアが3つ以下しか提供されていない場合、IMは自動的により単純な「アフィン」歪みにフォールバックします。4点以上(「画像登録」用)の場合は、与えられたすべての制御点の最適な歪みを検索するために最小二乗法が適合されます。将来:代替。4つの座標は、三角形と中心点を表すこともできます。三角形を固定して中心点を移動するか、その中心を固定して他の3つの座標を移動して、遠近法ビューを生成できます。歪みがどのように機能するかの詳細を確認したい場合は、以下の遠近感の内部構造を見てください。また、Gernot HoffmannによるPDF論文遠近法補正に示されているPostscript実装も参照できます。また、Leptonicaアフィンおよび遠近法変換も参照してください。

遠くの地平線の表示

座標を調整して画像の境界内に「消失点」を生成すると、遠近法歪みを使用して非常に珍しい効果を生み出すことができます。

  magick checks.png -mattecolor DodgerBlue \
          -virtual-pixel background -background Green \
          -distort Perspective '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          checks_horizon.png
[IM Output]
オリジナルの画像を取り囲む仮想ピクセルには「Green」を使用しました。これは仮想ピクセル背景設定で有効にしました。しかし、より興味深いのは、「-mattecolor」設定で定義された「青」色の出現です。この「青」色は、歪みによって生成されたピクセルが無効な領域を表しており、そのような領域では、「-distort」演算子は、「-mattecolor」設定をそのまま出力します。遠近法歪みの場合、結果として得られる画像の「空」に相当するピクセルはすべて無効とみなされます。また、「空」は、元の画像が表示されない「地平線」の側として定義されます。「空」は、歪みによって結果として得られる画像が非常に短縮された場合にのみ、遠近法歪み画像に表示されます。最終的な画像結果に「空」を表示させたくない場合は、「-background」と「-mattecolor」の両方を同じ色を使用するように設定するのが最善です。遠近法歪みは、特別な無限タイリング仮想ピクセル設定のいずれかを使用すると、さらに面白くなります。たとえば、ここでは「tile」設定を使用して、無限にタイリングされた平面を生成しました。

  magick checks.png  -virtual-pixel tile -mattecolor DodgerBlue \
          -distort Perspective '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          horizon_tile.png
[IM Output]
この画像に関する注意点です。無限にタイリングされた画像を要求すると、生成に非常に時間がかかります。画像が大きくなるほど、処理は遅くなります。「-distort」(またはその他の時間のかかる画像処理タスク)の進捗状況は、「-monitor操作制御設定を使用して監視できます。基本的に、地平線に近い単一のピクセルについては、ImageMagickは適切な色を判断するために、元の画像から膨大な数のピクセルの平均を計算する必要があります。これには非常に時間がかかる場合があります。ImageMagickは、情報をキャッシュし、さまざまな仮想ピクセル設定に関する組み込みの知識を使用することで、これらの地平線に近いピクセルを処理するのに使用する時間を制限しようとしますが、それでも時間がかかる場合があります。この方法の詳細については、上記の領域再サンプリングを参照してください。別の無限にタイル化された遠近法画像は、ランダム仮想ピクセル設定を使用することで生成できます...

  magick checks.png  -virtual-pixel random -mattecolor DodgerBlue \
          -distort Perspective '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          horizon_random.png
[IM Output]
ここで起こっていることは、画像の周囲のすべての仮想ピクセルは、画像自体の任意のピクセルのランダムな選択にすぎないということです。その結果、画像の地平線に向かって見るほど滑らかでぼやけたランダムノイズで構成された地面が生成されます。特定の繰り返しパターンなしに、奥行きのある自然な感覚を与えます。ここでは、上記を純粋な白黒のソース画像で繰り返しました。ただし、歪んだ実際の画像には興味がなく、生成された仮想ピクセルrandom」パターンのみに興味があるので、「-set option:distort:viewport」という特別な設定を使用して、見ている「歪んだ画像空間」の部分を変更しました。この設定は、表示されている歪んだ空間の領域の通常のサイズと位置を上書きします。この場合、仮想ピクセルのみを含み、歪んだ画像は含まない領域です。

  magick -size 90x90 pattern:gray50 -alpha set \
       -virtual-pixel random -mattecolor none \
       -set option:distort:viewport 120x120+100-15 \
       -distort Perspective '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
       +repage -size 120x50 gradient:dodgerblue-tomato \
       -compose DstOver -composite    sunset_horizon.png
[IM Output]
画像を完成させるために、ビューポートオフセットを削除し(「+repage」を使用)、透明な「空」(「alpha setmattecolor」を使用して設定)に夕焼け色のグラデーションを下敷きまたはDstOverしました。他の画像処理作業の背景として使用できる非常に興味深い画像です。歪みのパラメーターを調整して、地平線の高さと傾きを調整できます。
以下は、タイル状の遠近法歪みのより伝統的なテストです。

  magick pattern:checkerboard -scale 120x120 -normalize \
          -virtual-pixel tile  -distort Perspective \
             '0,0 10,61   119,0 60,60   0,119 5,114   119,119 125,110' \
          checkered_plain.gif
[IM Output]
私の研究では、上記のテストは誤解を招く可能性があることがわかりました。なぜなら、画像のほぼユニティスケール(遠い領域ではなく前景領域)に対する領域再サンプリング技術の品質を実際には示していないからです。それは、再サンプリングアーティファクトで説明されているような再サンプリングの問題を詳しく見ることです。この最後の画像は、ImageMagickがピクセルに適切な色を判断しようとする価値がないと判断した(現在の仮想ピクセル設定を考慮して)、地平線に近い「カットオフ」ポイントも示しています。しかし、EWAアルゴリズムをショートカットして、画像全体の平均色を使用します。これは、画像に存在する大きなスケールの対角線状のカラーパターンがあるため、この画像でのみ表示されます。画像の平均色は、歪み処理ごとに一度だけ計算され、最初に必要な場合にのみ計算されます。それを使用することで、ImageMagickは、通常は結果が画像の平均色になる場合に、地平線に近い色の計算にかかる時間を大幅に節約します。これは、楕円が非常に細長くなり、浮動小数点制限を超えるか、サンプリングピクセル数(楕円の境界平行四辺形)が入力ソース画像の4倍以上になった場合に発生します。これは現在、ユーザーが設定することはできません。

3Dボックス、遠近法レイヤー

歪んだ画像全体が正しく配置されたレイヤー(または「仮想キャンバス」)に確実に保持されるように設計された「+distort」の「プラス」形式は、画像を歪ませるために使用される同じ「コントロールポイント」がある場合、それらの点が「仮想空間」で整列することを意味します。これは、画像をレイヤーマージした場合、それらの画像もコントロールポイントに従って整列することを意味します。たとえば、ここでは、2つのエッジコントロールポイントが互いに整列し、ボックスの背骨を形成するように、「前面」と「背骨」の2つの画像を生成します。

  # Generate a Spine Image
  magick -size 200x40 xc:skyblue \
    -pointsize 20 -gravity north -annotate +5+0 'IM Examples' \
    -pointsize 10 -gravity south -annotate +0+0 'ImageMagick' \
    -stroke blue -strokewidth 2 -draw 'line 30,0 30,40' \
    -rotate -90 box_spine.jpg

  # generate the front cover
  magick -size 150x200 xc:skyblue \
    -fill black -pointsize 20 -gravity north -annotate +0+5 'IM Examples' \
    -fill blue -pointsize 15 -gravity northeast -annotate +5+28 'Box Set' \
    -fill black -pointsize 15 -gravity south -annotate +0+5 'ImageMagick' \
    -stroke blue -strokewidth 2 -draw 'line 0,169 150,169' \
    \( logo.gif -resize 100x100 \) \
    -gravity center -compose multiply -composite box_front.jpg

  # Distort both images and merge using common points.
  magick \
    \( box_spine.jpg -alpha set -virtual-pixel transparent \
       +distort Perspective \
           '0,0 -30,20  0,200 -30,179  40,200 0,200  40,0 0,0' \) \
    \( box_front.jpg -alpha set -virtual-pixel transparent \
       +distort Perspective \
           '0,0 0,0  0,200  0,200  150,200 100,156  150,0 100,30' \) \
    \
    -background black -compose plus -layers merge  +repage \
    -bordercolor black -compose over -border 15x2    box_set.jpg
[IM Output] [IM Output] ==> [IM Output]
プラスアルファ合成を使用して、「エッジ接続」されたピースを結合していることにも注意してください。これは、2つの画像間に「半透明のギャップ」が生成されるのを防ぐために必要です。詳細については、上記の3Dキューブの例と、2つのマスクされた画像の配置を参照してください。このような位置を使用すると、実際には「背骨」画像のほとんどが負の「x」位置に歪められます。したがって、結果の画像には仮想キャンバスに負のオフセットがあります。IMは、演算子のレイヤー「+distort」バージョンを使用する場合、これを行うのに問題はありません。レイヤーマージ演算子も、負のオフセットを持つレイヤー画像を処理し、2つの画像をきれいに「ステッチ」するように設計されています。最後に「+repage」を使用して、最終的な画像からその負のオフセットを削除する必要があります。そうしないと、Webブラウザーのような他のプログラムがそのような負のオフセットを理解できず、未定義の影響を引き起こす可能性があります。上記の例は、シェルスクリプト「box_set_example」にも配置されているため、より便利にダウンロードして使用できます。これをさらに進めて、「ボックス」の鏡像をその上に乗る表面に反射させて追加することもできます。ただし、その画像をよりリアルにするために、何らかの方法で再着色または暗くすることもできます。反射には、そのようなミラーリング手法が記載されています。
PHPのさらなる例は、境界線のないキャンバスフレーム上の「写真」のラッピングに関する議論の中で開発されました。詳細については、キャンバスラップ変換を参照してください。
最後に、Jean-François Hrenによるwww.animecoversfan.comの素晴らしい例を紹介します。これは、IMディスカッションフォーラムで詳しく議論されました。
[Diagram]
この画像は、アニメビデオボックスカバーの芸術的な画像を取得し、そのカバーを3つのセグメント(「カバー」、「背表紙」、「裏面」)に分割し、それぞれを個別に歪ませてレイヤー化された画像にし、4番目の「ディスク」画像を追加してマージすることで作成されました。次に、ハイライトとシェーディング効果(ハードライト画像合成を使用)と、境界線と半透明の影効果(CopyOpacityを使用)を追加することで、画像が完成しました。さらに驚くべきことは、入力画像から、プロセス全体が単一の「magick」コマンドで実行されたことです。これは、IMが何を実行できるか、および複雑なコマンドスクリプトを生成できるプロセスの優れた例です。多くのヒント、コツ、および一般的なデバッグ手法が含まれているため、フォーラムディスカッションを読むことをお勧めします。(その他の貢献例を歓迎します

遠近投影歪み

アフィン」歪みが「アフィン投影」の数学的係数を直接与えることで処理できるのと同様に、「遠近法」も「遠近投影」歪みの8つの係数で処理できます。前述のように、これらの数値は、ソース画像のポイントを宛先画像に前方マッピングするために使用される係数を表します。つまり、ソース画像x,yを宛先画像i,jにマッピングするために使用される数学的な値です。8つの浮動小数点引数は(指定された順序で)次のとおりです...
sx, ry, tx,
rx, sy, ty,
px, py
これらの係数値は、次の式を形成します。
Xd = sx*Xs + ry*Ys + tx   ,       Yd = rx*Xs + sy*Ys + ty


 px*Xs + py*Ys + 1.0   px*Xs + py*Ys + 1.0 
ここで "Xs,Ys" はソース画像の座標、"Xd,Yd" は変換先画像の座標です。内部的にImageMagickのDistortは、上記の式を逆転させ、適切な逆ピクセルマッピングを行い、"Xd,Yd" の座標をソース画像の "Xs,Ys" の色を参照するようにマッピングします。 'パースペクティブ投影' の最初の6つの値は、実は 'アフィン投影' と同じ係数ですが、より論理的になるように少し並び替えられています(「行列数学」の用語では、最初の6つの要素が対角的に転置されています)。追加の2つの引数 px,py は、歪み全体に対するスケーリング除数となり、与えられた値に応じて特定の方向で画像が小さく見え、歪んだ画像に遠近感の効果を与えます。これらの2つの値をゼロに設定すると、 'パースペクティブ投影' の歪みは 'アフィン投影' と同等になります。例を挙げます...

  magick rose: -alpha set -virtual-pixel transparent \
          -distort Perspective-Projection \
             '1.40, 0.25, 3.0    0.15, 1.30, 0.0    0.007, 0.009' \
          perspective_projection_rose.png
[IM Output]
与える行列は、ソース画像の座標を変換先画像の座標にマッピングする前方投影行列であることを覚えておいてください。ImageMagickは内部的に、変換先画像の座標をソース画像の座標にマッピングできるように行列を逆転させます。それらの値がどうなっているか確認したい場合は、詳細な歪みオプションを使用して、IMが内部係数をFXオペレーター式として出力するようにします(次を参照)。

パースペクティブの内部

パースペクティブ歪みの直前に "-verbose"(上記の詳細な歪み要約を参照)を追加すると、IMは "-distort" オペレーターのほぼ同等の代替となる2つのオペレーターを出力します。1つは非常に遅い "-fx" バージョンです(FX DIYオペレーターを参照)。もう1つは、前方マッピングのPerspective_Projection行列です。例を挙げます...

  magick rose: -alpha set -virtual-pixel transparent -verbose \
          -distort Perspective "0,0,3,0 0,46,10,46 70,0,70,7 70,46,60,40" \
          +verbose perspective_rose.png
[IM Output]
[IM Text]
最初のセクションであるパースペクティブ投影は、ソース座標を変換先座標にマッピングするために使用できます。式は上記の通りです。
  i = ( 1.430099*x +0.246650*y +3 )/( 0.006757*x + 0.009448*y +1 )  
  j = ( 0.147296*x +1.434591*y +0 )/( 0.006757*x + 0.009448*y +1 )  
これらの値を抽出して使用する例は、歪んだレイヤー画像の配置の最後の例に示されています。一方、2番目のFX相当セクションでは、画像歪みを実際に適用するために必要な逆ピクセルマッピングを実行する、別の8つの係数のセットを使用します。すなわち...
  x = ( 0.711858*i -0.108326*j -2.135575 )/(-0.004119*i -0.005877*j +1 )  
  y = (-0.073090*i +0.699571*j +0.219269 )/(-0.004119*i -0.005877*j +1 )  
出力FX相当式では、除数係数がXとY両方の座標式に共通であるため、最初に使用されることに注意してください。与える座標はすべて、ピクセル座標ではなく画像座標であることに注意してください。詳細については、画像座標とピクセル座標を参照してください。そのため、上記の適用前に、任意のピクセル位置に0.5を加算し、最終的な座標から0.5を減算して、ピクセル(描画)座標に戻す必要があります。これは、上記のFX相当コードで適用されていることがわかります。FX相当の最後のテストでは、変換先がソース画像に正しくマッピングできなかった無効な「空」ピクセルを処理します。ただし、そのようなピクセルには、"-mattecolor" の代わりに「blue」を代用するだけであり、パースペクティブ歪みの内部アルゴリズムが提供する水平アンチエイリアシングは提供しません。
パースペクティブ前方マッピングの例... これらのマッピングを使用すると、ある画像の特定の座標を別の画像の場所に(どちらの方向にも)変換できます。たとえば、ソースのバラ画像の中心にある暗い点は、ピクセル座標 '39,20' にあります。½ を加算して '39.5,20.5' を取得することで、画像座標にマッピングします。次に、x,y を i,j の式で使用して、変換先画像の座標 '44.2,24.1' にマッピングできます。最後に、½ を減算して「描画」ピクセル座標にして '43.7,23.6' の最終位置を取得します。そして、ここに入力画像と出力画像の両方に円を使用してその座標をマークします。

  magick rose: -fill none -stroke black \
          -draw 'circle 39,20 39,24'    rose_marked.png

  magick perspective_rose.png -fill none -stroke black \
          -draw 'circle 43.7,23.6 43.7,26.6'  perspective_rose_marked.png
[IM Output] ==> [IM Output]
ご覧のとおり、パースペクティブで歪んだ画像内の同じ点が、(サブピクセルレベルまで!)両方の画像で正しく配置されています!

バイリニア歪み

'バイリニア'歪み手法は、別のタイプの4点歪みを実装します。ただし、これは上記で見た 'パースペクティブ' 歪みほど単純ではありません。しかし、これからわかるように、非常に便利な代替歪みです。

前方バイリニア歪み

たとえば、グリッドが重ねられたマンドリルの特別なテスト画像を使用し、それをパースペクティブとバイリニアで歪めてみましょう。

  magick mandrill_grid.jpg -alpha set -virtual-pixel black \
       -distort Perspective \
              '0,0 26,0   128,0 114,23   128,128 128,100   0,128 0,123' \
       mandrill_pers.jpg
  magick mandrill_grid.jpg -alpha set -virtual-pixel black -interpolate Spline \
       -distort BilinearForward \
              '0,0 26,0   128,0 114,23   128,128 128,100   0,128 0,123' \
       mandrill_blin.jpg
[IM Output]
オリジナル
==> [IM Output]
パースペクティブ
[IM Output]
バイリニア
まず、両方の歪みが、1組の制御点から別の組の点に画像を正しくマッピングしたことに注意する必要があります。また、ソース画像のすべての水平線と垂直線も、両方の歪みで直線状を保っています。ただし、類似点はここで終わります。パースペクティブは、対角線さえも直線状を保つように、線間の間隔を狭めます。これにより、正方形の領域が小さくなり、右上隅に現実的な「遠く」の外観が与えられます。一方、バイリニアは画像の片側を「遠く」に見せたり、線を直線状に保とうとしたりしません。バイリニアが試みているのは、線間の間隔を一定に保つことですが、これにより、対角線が曲線になります。つまり、指定された線に沿った距離比を保持します。つまり、線分全体の相対的な長さは、線自体が曲がったり、湾曲したり、全体として短くなったりしても、線全体に沿って同じままになります。これは、上記の例のグリッド間隔が画像全体で一定のスケールを維持し、右上隅の歪んだ正方形が左下隅の歪んだ正方形とほぼ同じサイズであることを意味します。画像は「平らに見える」ままであり、異なる形状に歪んでいるだけです。(前方)バイリニアは、元の画像の水平線または垂直線が最終的な画像でも直線状を維持することを保証することに注意してください。つまり、直交して整列した長方形を取得し、指定された四辺形に変換して、元の長方形の各辺が線全体にわたって一定のスケーリングで直線状を維持します。この歪みの側面により、「BilinearForward」歪みが、はるかに複雑な「グリッド」歪みで役立ちます。つまり、隣接する2つの「四辺形」が、非常に異なって歪んでいる可能性があるにもかかわらず、エッジツーエッジで正しく整列します。ここに、「パースペクティブ」と「BilinearForward」の間の別の比較があります。これは、組み込みのバラ画像を非常に大きく歪ませて使用しています...


magick rose: -alpha set -virtual-pixel transparent \ -distort Perspective "0,0,3,0 0,46,10,46 70,0,70,7 70,46,60,40" \ perspective_rose.png magick rose: -alpha set -virtual-pixel transparent -interpolate Spline \ -distort BilinearForward "0,0,3,0 0,46,10,46 70,0,70,7 70,46,60,40" \ bilinear_rose.png
[IM Output]
オリジナル
==> [IM Output]
パースペクティブ
[IM Output]
バイリニア
(すべての直線を保持する)目的を達成するために、パースペクティブ歪みはほぼ画像全体を右側の小さい領域に「吸い込んでいる」ように見えますが、バイリニア歪みは中心にあるバラを中心にして結果を維持しました。繰り返しますが、距離比を保持し、バラを左右のエッジの間で等間隔に配置しました。すべては、画像の高さ方向に沿って高さを直線的に圧縮しただけです。この「BilinearForward」歪みの側面により、この歪みは「台形」歪みとしても知られています。つまり、1つの方向のみをスケーリングする場合は、1方向に画像を直線的に圧縮するだけです。その圧縮方向は、1つの軸に沿って整列するのではなく、角度を付けることもできます。
'BilinearForward'歪みを実行するために必要な逆ピクセルマッピングの複雑さのため、エリア再サンプリングは現在オフになっていることに注意してください。

そのため、極端な圧縮領域(2倍以上の係数)では、エイリアシング効果が見られる可能性が高いです(上記の例の線の端を参照)。ただし、スーパーサンプリングを使用するか、 '-interpolate Spline'を使用すると、最終的な画像の品質を向上させることができます。
IM v6.5.7-0以前では、 'BilinearForward'歪みはまだ開発中であり、特定の「縮退」ケースで問題があり、特定の場合に「黒」のエラー画像が発生する可能性がありました。

逆バイリニア歪み

水平線と垂直線のみが直線状のままであるため、「BilinearForward」歪みを使用して歪みを反転させることはできません。変換された画像のグリッド線はもはや水平または垂直ではないため、結果の画像では直線状のままにはなりません!たとえば、座標ペアを交換して、「前方」歪みを再適用すると(上記で「パースペクティブ」歪みを使用して行ったように)、元の画像を復元できません。

  magick mandrill_blin.jpg -alpha set -virtual-pixel black \
       -distort BilinearForward \
              '26,0 0,0   114,23 128,0   128,100 128,128  0,123 0,128' \
       mandrill_blin_back.jpg
[IM Output] ==> [IM Output]
指定された実際の座標は実際にそれ自体を正しく配置しましたが、画像歪みは反転されていません。要約すると、「BilinearForward」歪みはそれ自体の逆ではありません。画像を復元するには、わずかに異なるが密接に関連する歪みを使用する必要があります。「幾何変換」の数学的な逆は、「BilinearReverse」歪みとして実装されています。例を挙げます...

  magick mandrill_blin.jpg -alpha set -virtual-pixel black \
       -distort BilinearReverse \
              '26,0 0,0   114,23 128,0   128,100 128,128  0,123 0,128' \
       mandrill_blin_rev.jpg
[IM Output] ==> [IM Output]
前述のように、「BilinearForward」歪みの複雑さのため、エリア再サンプリングは現在オフになっており、これにより上記で深刻なエイリアシング効果が発生します。
'BilinearReverse'には 'BilinearFoward'と同じ距離比保持機能がありますが、任意の四辺形を直交して整列した長方形に変え、四辺形の辺が垂直および水平方向にマッピングされたときに直線状を維持することを保証します。上記でわかるように。
IM v6.5.1-2より前は、 'BilinearReverse'歪みは単に 'Bilinear'として実装されていました。
バイリニア歪み(IMの古いバージョンとLeptonicaライブラリを含む)のいくつかの実装では、上記のより単純な(逆)バージョンのバイリニア歪みのみが実装されていました。ただし、このような歪みは長方形の画像を「前方マッピング」するのにあまり適していません。たとえば、ここでは「BilinearReverse」を、おそらく「BilinearForward」歪みを使用する必要があった歪みに使用しようとしています。

  magick mandrill_grid.jpg -alpha set -virtual-pixel black \
       -distort BilinearReverse \
              '0,0 26,0   128,0 114,23   128,128 128,100   0,128 0,123' \
       mandrill_blin_rev2.jpg
[IM Output] ==> [IM Output]
ご覧のとおり、変換先の四辺形が直交する長方形ではなかったため、画像が大幅に歪んで、内側に曲がる線がたくさん生成されました。

タイリングされたバイリニア歪み

さて、「BilinearReverse」は長方形から「曲線」画像を生成しますが、この効果は、曲線的な3次元に見える表面を生成するように見える興味深いタイルパターンを生成します。たとえば、上記の遠くの水平線の表示に使用したものと同じ変換を適用すると、この興味深い結果が得られます。

  magick checks.png  -virtual-pixel tile  -mattecolor DodgerBlue \
          -distort BilinearReverse \
               '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          bilinear_rev_tile.png
[IM Output]
実際、「BilinearReverse」は決して「水平線」(無効なピクセル)を生成しません。一方、「BilinearForward」を使用すると、「空」または「無効なピクセル」(現在の"-mattecolor"で塗りつぶされています)がかなり定期的に生成される傾向があります。実際、タイルパターンはかなりおかしくなる傾向があります...

  magick checks.png  -virtual-pixel tile  -mattecolor DodgerBlue \
          -interpolate Spline  -distort BilinearForward \
               '0,0 20,60  90,0 70,63  0,90 5,83  90,90 85,88' \
          bilinear_fwd_tile.png
[IM Output]
前述のように、「BilinearForward」歪みの複雑さのため、エリア再サンプリングは現在オフになっており、これにより上記で深刻なエイリアシング効果が発生します。
そのため、「BilinearForward」のタイル形式の使用はお勧めしません。ただし、前方歪みを使用する場合は、予期しないグレーの「空」パッチの表示を防ぐために、適切な"-mattecolor"を定義することをお勧めします。

双一次の内部

ソース画像の座標を '前方マッピングされたバイリニア歪み' を使用して変換先画像にマッピングするための実際の式は...
Xd = C0*Xs + C1*Ys + C2*Xs*Ys + C3   ,       Yd = C4*Xs + C5*Ys + C6*Xs*Ys + C7
しかし、IMは逆ピクセルマッピング技術を使用して歪みを実装しているため、上記の式を逆にする必要があります。これは、二次方程式の解法、平方根、および代数でページ全体を埋めるような複雑な処理を必要とします。IMに詳細なFX相当の出力を要求すると、この複雑さを確認できます。たとえば、以前に作成したチェック画像を使用すると…

  magick checks.png -alpha set -virtual-pixel transparent -mattecolor none \
      -interpolate Spline -verbose -distort BilinearForward \
                   '0,0,0,0  0,90,0,90  90,0,60,30  90,90,90,90' \
      +verbose bilinear_checks.png
[IM Output]
[IM Text]
FX相当」の最終行にある「(rt > 0 ) ? red :」のチェックは、無効な負の平方根を避けるためのものです。これが、前の例で示した「空」の効果を作り出すチェックです。一方、逆バイリニア歪みは、より単純な多項式方程式を直接適用して、前の歪みを逆転させることができるため、はるかに単純です...

  magick bilinear_checks.png  -virtual-pixel transparent \
      -verbose -distort BilinearReverse \
                   '0,0,0,0  0,90,0,90  60,30,90,0  90,90,90,90' \
      +verbose bilinear_checks_rev.png
[IM Output]
[IM Text]
ご覧のとおり、結果の方程式は非常に単純です。これは、宛先座標からソース画像座標への逆ピクセルマッピングを行うために適用しているからです。
上記に見られるエイリアシング効果は、「BilinearForward」によって引き起こされており、「BilinearReverse」歪みによるものではありません。これは、現在、複雑さのために「フォワード」マッピングバージョンではエリアリサンプリングがオフになっているためです。
さらに詳しい情報については、Leptonica Affine and Perspective Transformsをご覧ください。

組み合わせバイリニア歪み

建設中
2つのバイリニア歪み手法を組み合わせることで、任意の四辺形を別の任意の四辺形に直接歪ませることができ、四辺形の辺を直線に保つことができます。基本的には、まず1つの四辺形を「逆」歪ませて長方形の画像にし、次にその長方形を「フォワード」歪ませて最終的な四辺形にすることができます。このタイプの歪みは、座標の任意の長方形グリッドを取り、それらを別の長方形グリッドの座標に歪ませることができることも意味します。これは「グリッド」歪みとして知られています。この手法は、画像モーフィングの主な基礎であり、2つの画像の上に線の長方形グリッドを定義し、それらを使用して画像を中間合成にマージしたり、1つの画像から別の画像に適切に変形するアニメーションを生成したりします。ただし、これはまだ実装されていませんが、計画されている追加機能です。

多項式歪み(多項式フィッティングを使用して歪ませる)

Polynomial」歪みは、以前のほとんどの歪み手法と同様に、制御点のペアをマッピングしますが、標準的な多項式方程式を使用します。これは、制御点が与えられる前に、1つの追加の引数が必要であることを意味します。
次数     X1,Y1 I1,J1     X2,Y2 I2,J2     X3,Y3 I3,J3     X4,Y4 I4,J4 . . . .
次数」引数は通常「1」以上の整数ですが、「1.5」の特殊な値も使用できます。これは、適用される2次元の数式(「x」と「y」の両方を使用)の「次数」または複雑さを定義します。たとえば、次数「1」の多項式は、次のような形式の方程式に適合します...
Xd = C2x*Xs + C1x*Ys + C0x   ,       Yd = C2y*Xs + C1y*Ys + C0y
これをアフィン投影に使用される方程式と比較すると、それが同等であることがわかります。各XおよびYの数式に3つの定数が必要なため、少なくとも3つのX、Y座標ペアを提供する必要もあります。それ以上の座標を指定すると、方程式は指定された座標に最小二乗法で適合されます。次の「次数」、つまり「1.5」は、「逆バイリニア」と同等です(方程式は、宛先座標をソース画像にマッピングするために使用されることを覚えておいてください)。
Xd = C3x*Xs*Ys + C2x*Xs + C1x*Ys + C0x   ,       Yd = C3x*Xs*Ys + C2y*Xs + C1y*Ys + C0y
逆バイリニア」歪みと同様に、最小で4つの座標が必要です。例としては...基本的には、次数「1」の方程式とまったく同じですが、多項式方程式に1つの項が追加されています。つまり、各方程式には軸ごとに4つの項があり、4つの定数があるため、IMがそれらの定数を決定できるように、少なくとも4つの座標ペアが必要です。

  magick mandrill_grid.jpg -alpha set -virtual-pixel black \
       -distort Polynomial \
              '1.5   0,0 26,0   128,0 114,23   128,128 128,100   0,128 0,123' \
       mandrill_poly_1.5.jpg
[IM Output] ==> [IM Output]
次数「2」では、多項式方程式がさらに拡張されて完全な二次適合になり、最小で6つの座標ペアが必要になります。
Xd = C5x*Xs2 + C4x*Xs*Ys + C3x*Ys2   + C2x*Xs + C1x*Ys + C0x
Yd = C5y*Xs2 + C4y*Xs*Ys + C3y*Ys2   + C2y*Xs + C1y*Ys + C0y
基本的には、次数「1」の方程式とまったく同じですが、多項式方程式に3つの追加項(次数2 + 1)が前置されています。つまり、各方程式には6つの項があり、6つの定数があるため、IMがそれらの定数を決定できるように、少なくとも6つの座標が必要です。これ以降の各次の多項式では、方程式のペアごとにさらに'次数'+1個の項が追加されます。したがって、次数「3」の三次適合多項式では、完全に定義するには最小で10個の座標ペアが必要であり、次数「4」の五次適合多項式では15個の座標ペアが必要です。詳細な歪み概要を使用して、指定した座標に合わせて多項式歪みが適合した結果の方程式を確認できます。大きな例として、グリッドの画像があります。また、そのグリッドをどのように歪ませたいかに関する座標の大規模なセット(ファイル「grid16_control_points.txt」に保存)もあります。次に、IMに、入力座標に「最適に適合」する三次多項式を生成するように要求しました。

  # warp image
  magick grid16.png -virtual-pixel gray \
          -distort polynomial "3 $(cat grid16_control_points.txt)" \
          grid16_polynomial.png

  # reverse image coordinate order
  awk '{print $3, $4, $1, $2}' grid16_control_points.txt \
                             > grid16_cp_inverse.txt

  # warp image back again
  magick grid16_polynomial.png -virtual-pixel gray \
          -distort polynomial "3 $(cat grid16_cp_inverse.txt)" \
          grid16_restored.png
[IM Output] ==> [IM Output] ==> [IM Output]
小さな「awk」スクリプトは、元のX、Y制御点ペアのセットを取得し、順序を逆にして、新しいファイルを使用して歪みを「元に戻す」ように試すことができます。
制御点ファイル「grid16_control_points.txt」の座標は画像座標であり、各数値はそれが参照するピクセルの中心を指します。追加の0.5がない場合、値は整数「ピクセル座標」になります。上記の画像座標とピクセル座標を参照してください。

これらの値は、画像ビューアを使用した手動検索のみによって決定されたため、実際には非常に正確ではありません。これが、逆歪みのアーティファクトの一部であり、多項式方程式の機能的な「最適適合」により、全体の歪み効果が軽減される可能性があります。

これは、多項式歪みが機能し、うまく機能するものの、正確なまたは可逆的な歪みではないことを示しています。基本的には、81個の座標が「平均化」されて、入力座標の数学的な「最適適合」を生成します。必要な最小値(10)ではなく、より多くの制御点(81)が提供されているため、要求された座標と完全に一致することが保証されている制御点はありません。ただし、この特定の例では、座標が予想される歪み結果に近い場合は、かなり近いはずです。多項式関数は、一般に、画像の端、特に角に沿って最も多くのエラーが発生します。これは、ピクセル位置だけでなく、エッジでのサンプリング領域(EWA)にも影響します。これは、使用される近似の自然な結果です。より高次の多項式を使用することもできますが、この場合は大きな改善は見られません。この特定のケースでは、多項式は実際には非多項式の三角関数に適合しようとしています。これらの関数の性質上、2番目の歪みは最初の歪みよりも不正確になります。この例は、後で説明する放射状の樽型歪み手法と非常に密接に関連しています。ただし、マッピングされる座標は、実際にはグリッド配置である必要はなく、座標マッピングの任意のセットにすることができます。このため、地理学者が航空写真を地理的な地図と位置合わせ(および重ね合わせ)するために、町、交差点、山の頂上、およびその他のランドマークの既知の位置を制御点として使用して、よく使用されます。
多項式歪みは一般的に可逆ではないため、IMが、指定されたソース画像に対して、宛先画像のビューポートの「最適適合」を計算することはできません。そのため、演算子の「+distort」形式は機能せず、通常の「-distort」操作にフォールバックします。ただし、歪みビューポートオプションを使用して、宛先画像のビューポートを定義することはできます。


円形および放射状の歪み手法

これは、歪みプロセスの主要な構成要素として放射状ベクトルを使用する歪みです。

円弧歪み(画像を円弧にカーブさせる)

Arc」歪み(IM v6.3.5-5現在)は、はるかに複雑な極座標歪み(下記参照)の単純なバリエーションです。デフォルトでは、指定された画像を、指定された角度で完全に円弧にカーブさせます。他の引数がない場合は、画像の水平方向の中心線と画像のアスペクト比のスケーリングをできる限り維持しようとします。これを行うために、最大4つの引数を取ります。
円弧角度   回転角度   上半径   下半径
ただし、「円弧角度」のみが必要であり、他の引数はオプションであり、必要に応じて指定された順序で追加できます。たとえば、画像を60度の角度で「Arc」にします…

  magick rose: -virtual-pixel White -distort Arc 60  arc_rose.jpg
[IM Output]
他の画像歪み演算子とは異なり、「Arc」歪みでは、ソース画像全体が表示されるように、結果の画像のサイズが常に設定されることに注意してください。これには、アンチエイリアシングエッジピクセルも含まれます。そのため、結果の画像が入力画像のサイズと一致することはめったにありません。

特定の歪みに対して結果の画像サイズを変更できるのは、ビューポート歪みオプションのみです。
2番目の引数 "rotate_agle" を追加すると、画像を円の周りに回転させることができます。たとえば、90度回転させることができます。

  magick rose: -virtual-pixel White -distort Arc '60 90'  arc_rose_rot.jpg
[IM Output]
特定の半径引数が言及されていないため、'Arc' 歪みメソッドは、元の画像のスケールを可能な限り維持しようと最大限の努力を払います。これを行うために、画像の水平中心線は、ソース画像の幅と指定された "arc_angle" に対する「理想的な半径」に設定されます。これは、画像をより大きな "arc_angle" で弧状にする場合、使用される中心線の半径も同じ係数で縮小することを意味します。そのため、中心線の半径は小さく、よりタイトになります。

  magick rose: -virtual-pixel White -distort Arc 120  arc_rose_3.jpg
[IM Output]
画像がより小さな円に収まるようになることに注意してください。しかし、画像の底辺はさらに小さな円です!画像を弧状にする角度をさらに大きく設定すると、底辺が歪みの中心に達し、それを超えて、ソース画像の下部が消滅します。

  magick rose: -virtual-pixel White -distort Arc 60   arc_rose_1.jpg
  magick rose: -virtual-pixel White -distort Arc 90   arc_rose_2.jpg
  magick rose: -virtual-pixel White -distort Arc 120  arc_rose_3.jpg
  magick rose: -virtual-pixel White -distort Arc 180  arc_rose_4.jpg
  magick rose: -virtual-pixel White -distort Arc 240  arc_rose_5.jpg
  magick rose: -virtual-pixel White -distort Arc 300  arc_rose_6.jpg
  magick rose: -virtual-pixel White -distort Arc 360  arc_rose_7.jpg
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]

完全な円環への円弧

より長い画像は、非常に大きな角度で「Arc」歪みをよりうまく適用できます。たとえば、長い画像(テキストメッセージなど)をリング状にすることができます。そして、ここで何が起こっているかを正確に理解できるように、異なる仮想ピクセルの背景色を設定しました。これにより、元の画像の境界を確認できます。

  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel Background  -background SkyBlue \
          -distort Arc 60     arc_circle_1.jpg
  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel Background  -background SkyBlue \
          -distort Arc 120    arc_circle_2.jpg
  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel Background  -background SkyBlue \
          -distort Arc 180    arc_circle_3.jpg
  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel Background  -background SkyBlue \
          -distort Arc 270    arc_circle_4.jpg
  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel Background  -background SkyBlue \
          -distort Arc 360    arc_circle_5.jpg
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
そして、ご覧のとおり、ラベル画像を完全な円に「弧」状にしました。完全な円の画像の結合部分をよく見ると、結合が完全ではないわずかなピクセルの線が見えるかもしれません。これは、周囲の「SkyBlue仮想ピクセルの背景の影響によるものであり、事実上、画像の2つのエッジを結合しています。完全な円を生成する場合は、これらの2つのエッジを正しく「結合」する仮想ピクセルメソッドを使用する必要があります。これは通常、Tileなどのタイリング仮想ピクセルメソッドのいずれかを使用することで行われます。

  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel Tile -background SkyBlue \
          -distort Arc 360   arc_circle_tile.jpg
[IM Output]
残念ながら、ご覧のとおり、これは画像を適切に結合するだけでなく、画像の重複した線がメインのリングの内外に生成されます。良くありません。IM v6.4.2-6の時点で、新しい仮想ピクセルメソッドであるHorizontalTileがこの問題を解決します。このメソッドは、画像を横方向にのみタイル状にするため、円状の画像に適した結合を作成しますが、タイルよりも上下の領域を現在の背景色で塗りつぶし、テキストの完璧な円を作成します。

  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel HorizontalTile -background SkyBlue \
          -distort Arc 360   arc_circle.jpg
[IM Output]
画像を「弧」状にする前に、入力画像を上下反転させて回転させると、元の画像の「上部」を円の内側の端に配置できます。もちろん、後で結果を再び直立させたいかもしれませんが、その機能はすでに「Arc」歪みメソッドに組み込まれています。

  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel Background -background SkyBlue \
          -rotate 180 -distort Arc '270 180'  arc_flip.jpg
[IM Output]
3番目の引数 "top_radius" は、計算される「理想的な」中心線の半径を上書きするため、画像の上が指定された半径の円になります。これにより、100ピクセルの幅のリングが作成されますが、アンチエイリアシング効果を考慮して、対応する画像の幅は102ピクセルです。

  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel HorizontalTile -background SkyBlue \
          -distort Arc '360 0 50'  arc_radius.jpg
[IM Output]
画像のアスペクト比は同じままなので、上記は基本的に以前と同じですが、要求された半径の円に合うようにスケーリングされただけです。半径は浮動小数点にすることができますが、円弧の中心は常にピクセルの「角」に揃えられるため、結果の画像の幅は依然として偶数のピクセルになります。4番目の "bottom_radius" 引数を指定すると、リングの幅または「半径方向の高さ」を完全に制御できます。

  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel HorizontalTile -background SkyBlue \
          -distort Arc '360 0 45 30'   arc_inner.jpg
[IM Output]
これにより、画像の半径方向のスケーリングが歪められ、事実上、半径方向のスケーリングが、結果の画像の「円弧幅」または角度から分離されます。言い換えれば、元の画像のアスペクト比は維持されなくなります。
入力画像の底辺が歪みの中心、つまり「極」で折り返して、円の内側を完全に埋めるように強制することもできます。

  magick -font Candice -pointsize 20 label:' Around the World ' \
          -virtual-pixel HorizontalTile -background SkyBlue \
          -distort Arc '360 0 45 0'   arc_fill.jpg
[IM Output]

円弧歪みの例

Arc歪みを使用して興味深い効果を生成できます。たとえば、長めの市松模様パターンをリング状に弧状にする場合(仮想ピクセルの設定「HorizontalTile」を使用すると...)

  magick -size 210x30 pattern:checkerboard -alpha set \
          -virtual-pixel HorizontalTile -background SkyBlue \
          -distort Arc 360   arc_checks.png
[IM Output]
デフォルトの仮想ピクセル設定である「Edge」を使用すると、より興味深い効果を生み出すことができます。

  magick -size 210x30 pattern:checkerboard  -virtual-pixel Edge \
          -distort Arc 360   arc_checks_edge.png
[IM Output]
もちろん、「Tile」設定も、興味深い「放射状」の効果を生成し、円形の市松模様パターンを生成できます。

  magick -size 210x30 pattern:checkerboard  -virtual-pixel Tile \
          -distort Arc 360   arc_checks_tile.png
[IM Output]
上記は、結果の画像の上部と下部の半径を制御することでさらに調整できます。ここにいくつかの「Arc」歪みの例をさらに示しますが、それらがどのように機能するかを理解するために、自分で試してください。何が思いつきますか?

  magick -size 90x1 pattern:gray50 -scale 900x100 -normalize \
          -virtual-pixel Tile  -set option:distort:viewport 100x100-50-50 \
          -distort Arc 360  +repage  arc_radii.gif
[IM Output]

  magick -size 400x100 pattern:hs_diagcross \
          -virtual-pixel Tile  -set option:distort:viewport 100x100-50-50 \
          -distort Arc '360 0 80 0' +repage  arc_cross.gif
[IM Output]

  magick -size 360x80 xc: -draw "fill none stroke black line 0,5 360,80" \
          -virtual-pixel White  -distort Arc '360 0 50 0'  arc_spiral.gif
[IM Output]

  magick tree.gif -set option:distort:viewport 120x60-60-60 \
          -virtual-pixel Dither  +distort Arc '180 0 25 0' \
          +repage arc_rays.gif
[IM Output]
この最後の例の「光線」は、擬似ランダムな「Dither仮想ピクセル設定の副産物であり、元の画像の左上隅からの「太陽」の色で奇妙なピクセルパターンが生じます。同じディザリング効果は、「木」の画像を囲む円形の「ダッシュ」の線も生成します。元の画像から興味深いエッジピクセルを追加するように変更した画像で、「Edge」設定を使用することにより、この効果の同様のより制御されたバージョンを実現できます。

円弧の中心点の配置

デフォルトでは、「Arc」は、画像が持っている可能性がある仮想キャンバスオフセットを完全に無視するか、画像が円弧状にされた「中心」の位置を報告しません。ただし、「中心点」の位置を知っておくことは非常に役立ちます。 "-distort" を使用する代わりに、特別なプラス形式である "+distort" を使用すると、画像に仮想キャンバスが与えられ、中心が仮想キャンバスの原点に配置されます。言い換えれば、画像の「0,0」ポイントが円弧の「中心」になるように設定されます。これは、円弧の「中心」が画像の中心ではない、完全な円よりも小さい角度で円弧状の画像を配置する場合に特に役立ちます。例として...

  magick logo: -resize x150 -gravity NorthEast -crop 100x100+10+0! \
          \( -background none label:'IM Examples' \
             -virtual-pixel Background +distort Arc '270 50 20' \
             -repage +75+21\! \)  -flatten  arc_overlay.jpg
[IM Output]
ここでは、テキストラベル「Arc」を作成し、演算子のプラス "+distort" 形式を使用して不完全な円に歪ませました。円弧の「中心」は、IMが画像の仮想キャンバスオフセットを使用して注意深く保持しました。これは、「!」フラグを使用して "-repage" を使用してオフセットを相対的に調整するだけで、結果のテキストの円を好きな場所に配置できることを意味します!上記の例では、ウィザードハットの先端(ピクセル座標75,21にあります)などです。残念ながら、仮想オフセットを使用して画像を配置するため、正確な配置は整数ピクセルサイズに制限されます。Arc歪みをサブピクセル定義の位置に配置することは、2回目の歪みを実行しない限りできません。ただし、これは極座標歪み(次を参照)で行うことができます。

極座標歪み(全円歪み)

Polar」歪み(IM v6.4.2-6で追加)は、上記の「Arc」歪みのより低レベルのバージョンです。ただし、自動的に「最適フィット」を行うことはなく、画像のアスペクト比を維持しようともしません。6つのオプションの浮動小数点引数は次のとおりです...
半径_最大半径_最小中心_X、中心_Y開始角度、終了角度
すべての引数は、スペースで区切られた位置ではオプションです。デフォルトでは、「CenterX,Y」は入力画像領域の真ん中にデフォルト設定されます。次に、上端全体が中心になり、下端が円の外側に完全に巻き付けられるように、完全な円の極座標画像が生成されます。左右の端は、画像の中央点の上で「-180」から「+180」の角度で出会います。「Radius_Max」は指定する必要があるため、正の値にする必要があります。 ただし、値「0」を指定した場合、中心と最も近い端の間の距離に設定されるため、他の値が指定されていない場合(デフォルト)、入力画像全体が画像の中央の円にマップされます。たとえば、すべてのデフォルトを使用して、世界の地図を極座標ビューに変換してみましょう。もちろん、完全な円の極座標マッピングを作成する場合は、「HorizontalTile」の仮想ピクセル設定を指定する必要があります...

  magick worldmap_sm.jpg -virtual-pixel HorizontalTile  \
          -background Black   -distort Polar 0   polar_arctic.jpg
[IM Output] ==> [IM Output]
もちろん、これは南半球を著しく歪ませ、南極大陸を「円盤世界」の円周全体に完全に巻き付けます。
ソース画像を回転させ、極冠だけを表示するように切り抜くことで、南極大陸の素晴らしい地図を生成できます。また、より見やすくするために、より大きな出力半径を指定し、Distortオペレーターの「プラス」形式を使用することにより、IMにこのサイズに出力画像を「適合」させるように依頼しました。

  magick worldmap_md.jpg -rotate 180 -crop 100%x25%+0+0 +repage \
          -virtual-pixel HorizontalTile -background Black \
          +distort Polar 80 +repage  polar_antarctica.jpg
[IM Output]
上記のものは厳密には地球の正しい見解ではないことに注意してください。これは、デカルト座標の地図は、極座標の画像ではなく、球体の表現であるためです。特別な「Radius_Max」の値である「-1」を正確に使用した場合、歪んだ画像の半径は、中心から最も遠いコーナー(対角線)までの距離に設定されます。これは、次に説明する完全な画像「DePolar」歪みの理想的な「逆」を提供するためです。(使用例については、以下の(De)Polarトリックを参照してください)。
Arc」歪みとは異なり、「Polar」(「デカルト座標から極座標」の歪みとも呼ばれます)は、ソース画像の「理想的な」アスペクト比を維持しようとしないことを忘れないでください。注意が必要です。
引数「CenterX,Y」は、結果として得られる画像の中心をサブピクセルオフセットで位置決めする場合に最も役立ちます。つまり、中心がピクセルの境界(整数)にあるのか、ピクセルの中心(0.5のオフセット)にあるのかを決定します。もちろん、仮想キャンバス「レイヤー」の位置も決定します。ただし、デフォルトでは、画像の中央(入力画像をビューポートとして使用する「-distort」の場合)、または「+distort」(レイヤー画像の場合)の場合は0,0の値が割り当てられます。次の引数「Start_Angle,End_Angle」はさらに使用頻度が低く、入力画像がカバーする角度を制限し、デフォルト値は-180〜180度(0は真下)です。「Arc」歪みと同様に、これを使用して結果の極座標画像を回転させることができます。ただし、「円弧」を生成するためにも使用できます。例を挙げます...

  magick worldmap_sm.jpg -virtual-pixel Black -background Black \
          +distort Polar  '60,20 0,0 -60,60' +repage  polar_arc.jpg
[IM Output] ==> [IM Output]
現在、IMは要求されたとおり、仮想画像の原点が座標0,0になるように配置された結果のレイヤー画像のサイズを縮小しないことに注意してください。引数のスタイル以外に、「Arc」歪みと「Polar」歪みの最大の違いはここにあります。また、左端(角度-60)が左側にあることにも注意してください。これは、「Y」軸が下向きである(すべての画像の回転と同じ)ことを考慮すると、数学的に正しいです。
もちろん、Arcと同様に、Virtual-Pixelタイリング効果を使用して反復パターンを生成できます。たとえば、これは最後の例とまったく同じですが、「HorizontalTileEdge」設定を使用しています...

  magick worldmap_sm.jpg -virtual-pixel HorizontalTile -background Black \
          +distort Polar  '60,20 0,0 -60,60' +repage  polar_arc_tiled.jpg
[IM Output]

DePolar歪み(極座標からデカルト座標へ)

これは本質的に「Polar」歪みの逆であり、まったく同じオプション引数のセットを持っています。6つのオプションの浮動小数点引数は次のとおりです...
Radius_Max   Radius_Min   Center_X,Center_Y   Start_Angle,End_Angle
ここでも、「Radius_Max」が「0」に設定されている場合、「CenterX,Y」から最も近いエッジまでの距離が使用されます。つまり、最大の円全体に含まれるものは、入力画像と同じサイズになるようにマッピングされます。たとえば、前の「ディスクワールド」をデカルトマップに戻してみましょう。

  magick polar_arctic.jpg  -distort DePolar 0  world_restored.jpg
[IM Output] ==> [IM Output]
入力画像のサイズは2つの歪みを介して維持されているため、上記の操作の結果は基本的に元のマップとまったく同じです。もちろん、画像は上部の「極」と半径の両方で圧縮されているため、出力は予想以上にぼやけています。
実際には、領域リサンプリングアルゴリズム(EWA)が円弧内のピクセルをサンプリングできないため、さらに悪化しています。そのため、領域リサンプリングは「DePolar」歪みではオフになっています。代わりに、次のセクションに示すようなスーパーサンプリング技術を使用することをお勧めします。
IMが「bestfit」(演算子の「+distort」形式を使用)を使用することを許可すると、「Radius_Max」を単位スケールに維持し、幅を「Radius_Max」と「Radius_Min」の中間の半径の円周距離に設定するように出力画像のサイズを変更します。これは本質的に極座標画像のアスペクト比を可能な限り維持しようとしますが、予想よりも長く細い画像が生成される可能性があります。例を挙げます。

  magick polar_arctic.jpg  +distort DePolar 0  world_restored_2.jpg
[IM Output] ==> [IM Output]

(De)Polarサイクルテクニック(放射状/角度ぼかし)

上で見たように、「Radius_Max」を「0」にすると、「Polar」(デカルト座標から極座標へ)歪みを使用する場合、画像全体が円にマッピングされ、同じ設定を使用すると、「DePolar」(極座標からデカルト座標へ)を使用することで、その円が長方形の画像にマッピングされます。ただし、長方形の画像を「DePolar」し、次に「Polar」を使用して歪みを元に戻す場合には、これはあまりうまく機能しません。たとえば、花の画像を使い、極座標を解除してから、特別な「Radius_Max」値「0」(半径=最も近いエッジ)を使用して復元してみましょう。

  magick flower_sm.jpg -virtual-pixel Black \
          -distort DePolar 0  flower_depolar.jpg
  magick flower_depolar.jpg \
          -virtual-pixel HorizontalTile -background black \
          -distort  Polar  0  flower_circle.jpg
[IM Output] ==> [IM Output] ==> [IM Output]
ここで、画像は最初の「DePolar」歪みによってクリップされたため、適切に復元されていません。それでも、これはそれ自体が有用な手法であり、既存の画像の完璧な円形マスクを、与えられた入力画像とは完全に独立した方法でサイズ変更して生成するために使用できます。この「DePolar」-「Polar」サイクルテクニックを正しく行うには、中心から最も遠い隅までの距離である半径を使用する必要があります。特別な「Radius_Max」値「-1」は、IMに「中心点」から最も遠い隅を半径として計算して使用するように要求します。

  magick flower_sm.jpg  -virtual-pixel Black \
          -distort DePolar -1  flower_depolar-1.jpg
  magick flower_depolar-1.jpg \
          -virtual-pixel HorizontalTile -background black \
          -distort  Polar  -1  flower_restored.jpg
[IM Output] ==> [IM Output] ==> [IM Output]
復元された画像はわずかにぼやけていますが、これは「DePolar」操作中に画像全体を保持するために必要な半径の圧縮によって引き起こされます。ただし、これは適切なスーパーサンプリングテクニックを使用することで修正できます(次の例のセットを参照)。しかし、なぜ画像をこの形式に変換して元に戻したいのでしょうか?さて、画像の「DePolar」中間バージョンに他の歪みを適用することで、非常に洗練された放射状または角度効果を非常に簡単に生成できます。たとえば、中間画像をロールすると、出力画像が回転しますが、隅がクリッピングされる可能性があります...

  magick flower_sm.jpg -virtual-pixel Black -distort DePolar -1 \
          -roll +15+0 \
          -virtual-pixel HorizontalTile -background Black \
          -distort  Polar  -1  flower_polar_rotate.jpg
[IM Output]
回転の方向はRotate OperatorまたはSRT Distortionの回転方向とは逆であることに注意してください。

Depolar-Polarサイクル問題

上記の画像回転では、回転した画像の端に沿って「階段状」の歪みが見られたかもしれません。これはよく知られた問題であり、画像の大きな円周を、入力画像のより小さな「幅」に圧縮することによって引き起こされます。たとえば、ここで、チェッカーボードテスト画像を取得し、何も変更せずに通常のDepolar-Polarサイクルを実行します。

  magick checks.png   -virtual-pixel Transparent \
          -distort DePolar -1   checks_depolar.png
  magick checks_depolar.png  -virtual-pixel HorizontalTile -background None \
          -distort  Polar  -1   checks_cycled.png
[IM Output] ==> [IM Output] ==> [IM Output]
中間画像の点における画像圧縮によって引き起こされるエイリアシング効果を明確に確認できます。また、最初の入力画像の「Depolar」変換中に通常の領域リサンプリングが使用されないという事実によって、さらに悪化しています。この問題を解決する最善の方法は、歪み出力スケーリングを使用して、中間画像を拡大し、最終画像を縮小することです。これにより、上記に見られた圧縮アーティファクトを削除するスーパーサンプリングされた結果が得られます。たとえば、これはより良い「no-op」Depolar-Polarサイクルであり、すべて1つのコマンドで実行できます...

  magick checks.png -virtual-pixel Background -background None \
          -set option:distort:scale 4  -distort DePolar -1 \
          -noop \
          -virtual-pixel HorizontalTile -background None \
          -set option:distort:scale .25 -distort  Polar  -1 \
          checks_cycled_ss.png
[IM Output]
ご覧のとおり、ひどいエイリアシング効果はほぼすべて解消されました。ただし、非常に背が高く細い画像では問題が再発する可能性があることに注意してください。最良のアイデアは、上記のようにスーパーサンプリングを使用し、「ランドスケープ」またはワイドな画像に制限することです。今行う必要があるのは、「-noop」演算子を、探している放射状および回転効果を生成するための適切なコマンドに置き換えることだけです。

Depolar-Polar効果の例

では、スーパーサンプリングを使用して、画像のより良い極回転を再び示しましょう。ただし、中間画像が4倍大きいため、画像ロールの量も4倍大きくする必要があることに注意してください。

  magick flower_sm.jpg   -virtual-pixel Black \
          -set option:distort:scale 4   -distort DePolar -1 \
          -roll +60+0   \
          -virtual-pixel HorizontalTile -background Black \
          -set option:distort:scale .25 -distort Polar -1 \
          flower_polar_rotate_ss.jpg
[IM Output]
ご覧のとおり、エッジに沿った「階段状」の効果は解消され、画像の結果ははるかに高品質になりました。
または、中間画像の単純な線形ぼかしを適用することもできます(これは、画像を再び圧縮および拡大することで実現されます)。

  magick flower_sm.jpg -virtual-pixel Black \
          -set option:distort:scale 4   -distort DePolar -1 \
          -scale 10%x100%\! -filter Gaussian -resize 1000%x100%\! +filter \
          -virtual-pixel HorizontalTile -background Black \
          -set option:distort:scale .25 -distort Polar -1 \
          flower_angular_blur.jpg
[IM Output]
結果は、画像の「回転ぼかし」と非常によく似ています。これは、誤って名付けられた放射状ぼかし演算子に似ていますが、まったく同じではありません。実際、結果はその特殊なぼかし方法よりも高品質です。適用されたさまざまな形式の仮想ピクセル設定で「black」色を使用すると、エッジがわずかに暗くなりますが、上記の場合はそれほど悪くありません。「黒」のエッジ効果を取り除く1つの方法は、代わりに「transparency」色を使用し、完了したらアルファチャネルを完全にオフにして、IMが計算した実際の色だけを残すことです。もう1つは、2つの「エッジ」仮想ピクセルメソッド(「Edge」と「HorizontalTileEdge」)を使用することです。これにより、画像の端が定義されていない仮想キャンバス空間に拡張されます。

  magick flower_sm.jpg -virtual-pixel Edge \
          -set option:distort:scale 4   -distort DePolar -1 \
          -scale 10%x100%\! -filter Gaussian -resize 1000%x100%\! +filter \
          -virtual-pixel HorizontalTileEdge -background Black \
          -set option:distort:scale .25 -distort Polar -1 \
          flower_angular_blur_edge.jpg
[IM Output]
これにより、エッジの近くではるかに優れた結果が得られます。
今回は、サイズ変更圧縮ではなく、モーションブラー演算子を使用して、画像の極座標バージョンを垂直方向にぼかすことで、画像の中心から外側に移動する放射状の縞模様を生成できます...

  magick flower_sm.jpg   -virtual-pixel Black \
          -set option:distort:scale 4   -distort DePolar -1 \
          -virtual-pixel Edge   -motion-blur 0x28-90 \
          -virtual-pixel HorizontalTile -background Black \
          -set option:distort:scale .25 -distort Polar -1 \
          flower_radial_blur.jpg
[IM Output]
結果が画像のハイライト(花びら)だけをぼかすようにするには、明るくするを使用してこれを元の画像と合成できます。これにより、ぼやけた明るい色だけが表示されたままになり、暗い色が明るい領域にぼやけたり、花の中央にある黄色の点が消えたりすることがなくなります。

  magick flower_sm.jpg  flower_radial_blur.jpg \
          -compose Lighten -composite   flower_radial_blur_lighten.jpg
[IM Output]
別の例については、星と彗星も参照してください。ここでは、「Polar」歪みを適用する前に、中間「DePolar」画像を直接生成しています。DePolar-Polarサイクルの特別な用途と、これらの歪みが長方形の画像に対して完全に可逆であることを確認するように主張したFred Weinhausに特に感謝します。彼はこのテクニックを、多くのImageMagickスクリプト(「bump」、「ripples」、「striations」など)でうまく利用しています。

バレル歪み(レンズ歪みの補正)

バレル歪み(IM v6.4.2-4で追加)は、写真のカメラレンズによって引き起こされる球面収差を補正するために特別に設計されています。つまり、樽型や糸巻き型の効果などの歪みであり、これらは事実上互いに逆の効果です。このオペレーターをレンズ歪み補正に使用する実際の適用については、「レンズ補正」のセクションを参照してください。歪みは、ヘルムート・ダーシュ教授によって定義された、ABC、およびDとして知られる4つの係数値のセットに基づいて実装されています。彼のウェブサイトはその後消滅しました。サイトのWayback Machineアーカイブを樽型歪みの補正で見ることができます。これらの値は基本的に、次のような歪み方程式を形成します。
Rsrc = r * ( A*r3 + B*r2 + C*r + D )
ここで、"r" は出力半径、"Rsrc" はピクセルカラーを取得する元のピクセルです。半径は正規化されており、入力画像の最小幅または高さの半分に対して半径 = '1.0' となります。これは逆に見えるかもしれませんが、これは、結果の画像を完全にカバーするために逆ピクセルマッピング技術が使用されているためです。4つの係数(ABC、およびD)は、特定のカメラ、レンズ、ズームの組み合わせに対して固定されています。これら3つは通常、EXIFプロファイルに画像とともに保存されます。これは、カメラのこれらの値を入手すると、そのカメラとレンズの組み合わせで撮影されたすべての写真に存在する球面レンズ歪みを除去するために使用できることを意味するため、重要です。 'Barrel' 歪みメソッドに必要な引数は次のとおりです。一般的に、3つまたは4つの値のみを提供します...
A   B   C   [ D   [ X , Y ] ]
オプションのXY引数は、放射状歪みのオプションの「中心」を提供します。それ以外の場合は、指定された画像の正確な中心にデフォルト設定されます(仮想オフセットに関係なく)。係数は、4つのAからDの値がすべて「1.0」に合計される場合、画像の最小幅/高さが変更されないように設計されています。このため、D(画像の全体的なスケーリングを制御します)が指定されていない場合、4つの値がすべて「1.0」に合計されるように設定されます。パラメータ '0.0 0.0 0.0' (A=B=C=0.0およびD=1.0と同等)を使用すると、入力画像は変更されず、この歪みの「no-op」引数になります。以下は、元のウェブサイトからの例で、写真の撮影に使用されたカメラの提供された係数を使用しています。

  magick barrel_distorted.jpg -virtual-pixel black \
          -distort Barrel "0.0 0.0 -0.075 1.1" \
          barrel_distorted_fixed.jpg
[IM Output] ==> [IM Output]
画像の歪みが修正され、建物の柱がまっすぐになっていることに注目してください。ただし、4つの係数の合計が1.0より大きい値になったため、画像は少し縮小され、上部と下部の中央端に小さな黒い領域が生成されました(指定された仮想ピクセル設定に従って)。入力係数にそれぞれ0.2を追加した場合の効果を次に示します。ここでも、値の合計が1.0より大きいため、結果として得られる歪んだ画像は小さくなります。

  magick checks.png -virtual-pixel gray \
          -distort Barrel "0.2 0.0 0.0 1.0"   barrel_checks_A.png
  magick checks.png -virtual-pixel gray \
          -distort Barrel "0.0 0.2 0.0 1.0"   barrel_checks_B.png
  magick checks.png -virtual-pixel gray \
          -distort Barrel "0.0 0.0 0.2 1.0"   barrel_checks_C.png
  magick checks.png -virtual-pixel gray \
          -distort Barrel "0.0 0.0 0.0 1.2"   barrel_checks_D.png
[IM Output] [IM Output] [IM Output] [IM Output]
0.2を引くと、逆の効果が得られますが、(画像を縮小するために)より大きな 'D' 値を使用して効果をオフセットしたので、結果をよりよく見ることができます。

  magick checks.png -virtual-pixel gray \
          -distort Barrel "-0.2 0.0 0.0 1.3"   barrel_checks-A.png
  magick checks.png -virtual-pixel gray \
          -distort Barrel "0.0 -0.2 0.0 1.3"   barrel_checks-B.png
  magick checks.png -virtual-pixel gray \
          -distort Barrel "0.0 0.0 -0.2 1.3"   barrel_checks-C.png
  magick checks.png -virtual-pixel gray \
          -distort Barrel "0.0 0.0 0.0 1.3"    barrel_checks-D.png
[IM Output] [IM Output] [IM Output] [IM Output]
Aの値がBよりも大きな効果を生み出し、BCよりも大きな効果を生み出すことに注意してください。一方、Dは結果の全体的なスケーリングを提供します。これにより、各係数を使用して画像を調整し、外側の端付近の1つの歪み、中央に向かって別の歪みを補正できます。たとえば、一方が糸巻き型、もう一方が樽型の場合などです。非常に用途が広い。上記の係数(ABC、およびD)は、画像の最小幅または高さの半分である「正規化」された半径(極座標歪みの「0」半径設定のような)で動作するように設計されています。つまり、これらは画像サイズに依存しません。したがって、特定のカメラが生成するすべての画像に対して、その画質サイズ(カメラ設定)に関係なく、または画像を小さくリサイズした場合でも、同じ値のセットを使用できます。各係数に適切な乗数/除数を使用することにより、他の「正規化」された半径値を使用するように係数値を調整できます。たとえば、最大幅/高さの半分を使用したり、対角半径を使用したりするなどです。
ヘルムート・ダーシュ氏はまた、写真の歪み補正にはLABカラースペースを使用することを検討する必要があるとも指摘しています。これにより、より優れたカラー補間が生成されるためです。これは、(リサイズを含む)すべての歪みについても実際に当てはまる可能性があります。

テストでは、LAB空間はsRGBと同じくらい非線形であることが示されていますが、極端な値がクリップされた場合に色の歪みの可能性を回避できます。人間の色の知覚、およびカラースペース補正によるリサイズの実例を参照してください。

また、x軸とy軸に異なる係数セットを宣言して、いくつかの異常な歪みを生成することもできます。
Ax Bx Cx Dx   Ay By Cy Dy   [ X , Y ]
別々のXおよびY引数の使用は、フレッド・ワインハウスのpinbarrelスクリプトでプロトタイプ化されましたが、彼の引数は逆順で、Dが最初でAが最後でした。 'y'係数セットのみに適切なD値を持つ正のC値を使用することにより、画像を歪ませて、中央で垂直方向に膨らませることができます。

  magick rose: -alpha set -virtual-pixel transparent \
          -distort Barrel "0.0 0.0 0.0 1.0   0.0 0.0 0.5 0.5" \
          barrel_bulge.png
[IM Output]
同様に、負のC値を使用すると、画像の真ん中を「つまむ」ことができます。

  magick rose: -alpha set -virtual-pixel transparent \
          -distort Barrel "0.0 0.0 0.0 1.0   0.0 0.0 -0.5 1.9" \
          barrel_pinch.png
[IM Output]
または、X係数に反対の効果を追加することにより、指の間で画像を絞っているように見せ、側面を膨らませることができます。

  magick rose: -alpha set -virtual-pixel transparent \
          -distort Barrel "0.0 0.0 0.5 0.5   0.0 0.0 -0.5 1.9" \
          barrel_pinch_2.png
[IM Output]

バレル逆歪み(代替のバレル歪み)

'BarrelInverse' 歪みメソッドは、前のバレル歪み歪みメソッドと非常によく似ており、実際には同じ引数のセットを受け取ります。ただし、適用される式はわずかに異なり、方程式の主要部分は半径を分割します。つまり、方程式が反転しました。
Rsrc = r / ( A*r3 + B*r2 + C*r + D )
この方程式は、'Barrel'歪みの「逆」を生成しません。以前の歪みを「元に戻す」ために使用することはできません。
この結果、ABCの「負」の形式を使用し、Dで同等の調整を行って、類似しているがわずかに異なる結果を得ることになります。レンズ歪みを補正する方法(PDF)などの一部のソースでは、この形式のレンズ補正歪みでより良い結果が得られることが示唆されています。たとえば、この形式の歪みを使用した最後の「ピンチ」の例と同等のものを以下に示します。

  magick rose: -alpha set -virtual-pixel transparent \
          -distort BarrelInverse "0.0 0.0 -0.5 1.5   0.0 0.0 0.3 0.5" \
          barrel_inv_pinch.png
[IM Output]


投影歪み

これらは、ある面上に存在する画像を別の面に投影またはマッピングするために使用される歪みです。投影線は平行であるか、特定の場所から放射状に伸びている場合があります。技術的には、アフィンおよびパースペクティブ歪みも、ある平面上の画像を別の平面に(それぞれ平行投影および放射状投影を使用して)「投影」するという意味で「投影」ですが、これらは非常に一般的であるため、上記の独自の例で詳しく調べています。ここでは、IMディスカッションフォーラムの助けを借りて実装された、より珍しい「投影歪み」を紹介します。

円柱から平面へ

'Cylinder2Plane'歪みは、シリンダーの中心の点から、そのシリンダーに接する平面への放射状投影歪みです。
[diagram]
この配置は、P.90カメラとして知られる特別なピンホールカメラの典型です。ここでは、90度の円弧の写真がカメラ内のシリンダーを形成するフィルムにキャプチャされます。以下に、そのようなカメラからの写真の例を示します...
[photo]
この問題は、フィルムの物理的な配置のために、結果として得られる画像が歪んでおり、直線が湾曲した弧になることです。本質的に、湾曲した表面が「点」投影ソース(ピンホール)の周りに巻き付いています。通常のピンホールカメラは、点光源から平面に投影しているため、この問題がないことに注意してください。 'Cylinder2Plane' 歪みは、円筒状の配置から画像を平面に投影することにより、これを修正します。次のパラメータを使用します...
fov_angle   center_x,y   fov_output   dest_center_x,y
最初のパラメータであるカメラの視野角のみが必要です。P.90カメラの場合、90 mm(放射状)の焦点距離と標準の57 mm幅のフィルムを使用しており、これにより、90 / 57 * 180/piまたは90.467度の「視野」が生成されます。たとえば、ここでは、P90の写真を平面に投影して、画像がより「正常」に見えるようにし、直線を再びまっすぐにします。

  magick p90_orig.jpg -virtual-pixel Gray \
          +distort Cylinder2Plane 90.467  p90_plane.png
[IM Output]
元の画像の歪んだすべてのピクセルを表示するために歪みの「プラス」バージョンを使用しているため、画像の幅と高さの両方が変更されていることに注意してください。投影のため幅は広くなり、垂直中心線に沿った実際の画像の高さは変更されていません。写真とアルゴリズムは、IMディスカッション湾曲したフィルム面を補正するからのものです。このディスカッションは、ピンホールカメラのアルゴリズムによるビネット補正に関する別のディスカッションにも発展しました。
特別な'fov_output'が指定されている場合、結果の出力画像の幅(通常はビューポートサイズ)がこの角度と正確に一致するように、結果の出力画像をスケーリングします。ビューポートが指定されていない場合は、画像の1:1のスケーリングに最も近い近似を行うために、最適な一致が有効になり、画像の端を整数に合わせます。歪みの中心点パラメータ(入力の接線と地平線点)。最後の「center」パラメータは、ビューポートイメージ「レイヤー」での結果の正確な浮動小数点位置を制御します(つまり、サブピクセルの変換)。これは'center_x,y'パラメータとともに、大きな画像の一部を抽出できます。たとえば、大きな360度パノラマ画像から小さな90度のビューを抽出するなどです。将来:360度パノラマから小さなフラットな「表示」画像を抽出したり、360度ゆっくりとパンするアニメーション。

平面から円柱へ

'Plane2Cylinder'歪みは上記の投影の逆で、次のパラメータを使用します...
fov_angle   center_x,y
たとえば、これは以前のP.90カメラの例を元に戻します。

  magick p90_plane.png -virtual-pixel Black \
          +distort Plane2Cylinder 90.467  p90_restored.png
[IM Output]
結果には、以前に追加された追加のピクセルが含まれており、さらに多くのピクセルが追加されています。これらは上記の結果からトリミングする必要があります。ここでは、この歪みを使用して、フィルムスプロケットのエッジ穴を備えた「フィルムストリップ」のアニメーションを生成します。

  magick -size 12x12 xc: -draw 'circle 6,6 6,2' -negate \
          -duplicate 5 +append +duplicate \
          rose: +swap -background black -append \
          -duplicate 3 +append \
          -virtual-pixel HorizontalTile -background SkyBlue \
          -duplicate 19  -distort SRT '%[fx:72*t/n],0 1 0 0,0' \
          -distort Plane2cylinder 115 \
          -bordercolor Skyblue -border 0x3 -set delay 5 \
          film_strip_anim.gif
[IM Output]
説明
  • まず、穴の画像を描画し、複製して追加し、6つの穴のシーケンスを作成します。その後、再度複製します。
  • 次に、組み込みのバラの画像を追加し、これらのスプロケット穴の2つのコピーの間に挟み込み、黒の塗りつぶしでまとめて追加して、最終的なフィルムストリップの単一フレームを作成します。
  • これを複製して、最終画像の長さを定義する4フレームのフィルムストリップを作成します。
  • SRT「変換」歪みを使用して、20フレームのアニメーションが作成されます。歪みアニメーションを参照してください。
  • 次に、これらの20フレームのそれぞれを、仮想ピクセル設定を使用してフィルムストリップの無限の水平タイルを生成し、115度の円弧上のシリンダー上に歪ませます。
  • この場合の角度は、入力画像の幅に対してのみであり、歪みの「プラス」バージョンを使用しなかったため、最終画像の幅は180度を超えています。したがって、歪んだ幅が幅方向に縮小しますが、出力画像は縮小しません。
  • 最後に境界線を追加し、アニメーション設定を適用します。


マルチポイントおよびフリーフォーム歪み

シェパードの歪み(タフィーのような歪み)

シェパード法(IM v6.4.2-4 で追加)は、与えられた制御点の動きを利用して、画像に「局所的な」効果を与えるように歪ませます。これは、元の画像を表す厚い「タフィー」の塊にピンを打ち込み、そのピンを動かすことに相当すると考えるとよいでしょう。より技術的には、逆二乗距離補間によって点を移動させます。制御点が1つだけ使用された場合、当然ながら画像全体が移動(平行移動)され、これは1点の「アフィン」歪みと同じになります。あまり面白くありません。そこで、2つの制御点を動かしてみましょう。例えば、「コアラ」の耳(「30,11」と「48,29」)を引っ張って、コアラをいじめてみます。

  magick koala.gif -virtual-pixel Black \
          -distort Shepards '30,11 20,11  48,29 58,29' \
          koala_ear_pull.png
[IM Output] ==> [IM Output]
ご覧のように、2つの制御点の間にある画像の部分は、制御点の動きによって引き伸ばされました。しかし、画像の下部など、制御点の近くを含む画像の他の部分は、ほぼそのまま残っています。制御点の間の真ん中にある領域は、制御点が要求どおりに配置されるように引っ張られ、引き伸ばされました。あまり目立たないかもしれませんが、制御点の反対側にある部分も圧縮されており、遠く離れるほど、制御点が結果に与える影響は少なくなります。つまり、この歪みは「局所的な」歪みを生成します。
このことをよりよく理解するために、(歪みビューポートを使用して)視野を広げてみましょう。

  magick koala.gif -virtual-pixel Black \
          -set option:distort:viewport 115x115-20-20 \
          -distort Shepards '30,11 15,11  48,29 58,29' \
          +repage koala_ear_pull_2.png
[IM Output]
ご覧のとおり、画像の形状もコアラの「頭」の伸びに対応するように歪められています。
この効果を避けるためには、画像の隅や端の一部も「固定」して動かないようにするのが一般的です。

  magick koala.gif -virtual-pixel Black \
          -set option:distort:viewport 115x115-20-20 \
          -distort Shepards '30,11 15,11  48,29 58,29
              0,0 0,0  0,74 0,74   74,0 74,0  74,74 74,74' \
          +repage koala_ear_pull_3.png
[IM Output]
1点だけを動かしながら、他の点(この場合は隅だけ)を固定するだけでも役立ちます。たとえば、コアラの鼻(「28,24」)を画像の真ん中に移動してみましょう。

  magick koala.gif -virtual-pixel Black \
          -distort Shepards '28,24 37,37
              0,0 0,0  0,74 0,74   74,0 74,0  74,74 74,74' \
          +repage koala_move_nose.png
[IM Output]
この特定の例は、Fred Weinhaus が彼の単一点「アニメーションモーフ」スクリプト "shapemorph" で使用した歪みであるため、特殊です。ただし、彼の元のスクリプトは、遅い DIY FX 演算子を使用していました。シェパード歪みが IM にまだ追加されていなかったためです。このスクリプトは、実際に シェパード歪みの元のアイデアの出どころでした。

画像の領域を移動する

さらに、セクションの周りの点のセットをまとめて移動することで、画像全体のセクションを移動することもできます。たとえば、頭の周りの点(赤線)を使用し、移動させたくない画像の部分(緑線)を固定して、コアラの頭を横に移動してみましょう。

  magick koala.gif -virtual-pixel Black -distort Shepards \
            '19,8, 29,8   19,27 29,27   26,34 36,34
                 33,37 43,37   36,37 46,37   53,37 63,37   58,25 68,25
             13,20 13,20  17,28 17,28  25,36 25,36
                 35,39 35,39   46,40 46,40   50,43 50,43 ' \
          +repage koala_head_move.png
[IM Output] ==> [IM Output]
頭は移動しましたが、頭の端がひどく歪んでいることに注意してください。これは、歪みが領域ではなく点を移動するためです。これらの端をマークする点が離れすぎていると、画像はタフィーやゼリーのように、それらの点の間で垂れたり、漏れたり、曲がったりします。(余談:実際の用語は「ゴムシート」または「風船」を伸ばすことです)。また、2つの制御点が近くにあり、異なる方向や量に移動する場合、画像はそれらの周囲で局所的に渦巻いたり曲がったりする可能性があります。制御点は正しい場所に配置されますが、周囲のすべてのものはその目標を達成するためにひどく歪められます。それが、頭の端に沿って起こっていることです。それでは、端をマークする点はどの程度近くにあるべきでしょうか?基本的には、異なる方向に移動している他の点までの距離の少なくとも半分です。したがって、より多くのエッジポイントを追加するか、固定ポイントと移動ポイントの間隔を広げる必要があります。これにより、画像を伸縮できる空間をより明確に定義できます。また、画像全体が頭と一緒に左に移動したことにも注意してください。固定されたか、特定の目的地に移動された制御点のみが、正しく配置されることが保証されます。制御点から遠く離れた画像の部分も、すべての制御点の動きのおおよその平均に基づいて移動します。したがって、画像全体に散在するより多くの「固定」点を持つか、一般的な平均移動をオフセットするために、画像の外部にいくらかの距離を置いて負に移動した点を持つ方が良いでしょう。制御点を複製または二重化(2回リスト)して、特定の点がその領域の歪みに対してより大きな影響力または「力」を与えることもできます。これが、「頭を横に移動」する別のバージョンです。ただし、今回は、移動(赤)ポイントと固定(緑)ポイントの間隔をいくらか広げました。歪んだ画像の全体的な平均移動を減らすために、さらに多くの固定点も追加しました。

  magick koala.gif -virtual-pixel Black -distort Shepards \
            '15,15, 25,15   19,27 29,27   26,34 36,34
                33,37 43,37   36,37 46,37    53,37 63,37
             10,2 10,2   2,10 2,10   4,55 4,55   14,47 14,47
                25,47 25,47 45,51 45,51   55,45 55,45
                5,70 5,70  15,60 15,60   55,60 55,60   70,70 70,70' \
          +repage koala_head_move_2.png
[IM Output] ==> [IM Output]
上記で最後にやるべきことは、上記の定義されていない黒い領域の色を何にするかを設定するために、より良い「-virtual-pixel」設定を単純に設定することです。

シェパードと画像の回転

この歪みの一つの側面は、回転の形式を好まないことです!たとえば、パースペクティブバイリニアフォワードと並んで、シェパード歪みの繰り返しを示します。


magick mandrill_grid.jpg -alpha set -virtual-pixel black \ -distort Perspective \ '0,0 26,0 128,0 114,23 128,128 128,100 0,128 0,123' \ mandrill_pers.jpg
magick mandrill_grid.jpg -alpha set -virtual-pixel black -interpolate Spline \ -distort BilinearForward \ '0,0 26,0 128,0 114,23 128,128 128,100 0,128 0,123' \ mandrill_blin.jpg magick mandrill_grid.jpg -alpha set -virtual-pixel black -interpolate Spline \ -distort Shepards \ '0,0 26,0 128,0 114,23 128,128 128,100 0,128 0,123' \ mandrill_shep.jpg
[IM Output]
オリジナル
==> [IM Output]
パースペクティブ
[IM Output]
バイリニア
[IM Output]
シェパード
シェパード歪みは、他の2つの歪み方法と比較して、非常に曲線的な画像を生成することに注意してください。これは、与えられた制御点の近くの領域で画像を正確に保持しようとするためです。そして、それには画像の回転が含まれます。この「保持」の結果として、グリッドは、実際の制御点で「直交」したままになるように湾曲しています。制御点の「ピン」は実際には丸いピンではなく、「十字」であり、画像を保持する「ゼリー」または「ゴムシート」も画像の回転を保持するように強制しているようなものです。これは、この歪みが生成する多くの「渦巻き」効果の源でもあります。たとえば、画像内の2つの点を互いに押し合わせると、画像は回転するのではなく渦巻きます。たとえば、コアラの耳を離すのではなく、互いに押し合わせようとしてみましょう。

  magick koala.gif -virtual-pixel Black \
          -distort Shepards '30,11 40,11  48,29 38,29' \
          koala_ear_push.png
[IM Output] ==> [IM Output]

シェパードのパワーファクター

通常、シェパード IWD (逆加重距離) の距離重みは、逆二乗則 (1/r2) に従いますが、IM v6.8.0-10 以降では、エキスパートの 定義 'shepards:power' を使用して、グローバル重みの「パワーレベル」を制御できるようになりました。定義しない場合は値が 2.0 ですが、定義を小さくすると、歪んだ画像の全体的な平均変位から移動した制御点の周囲により局所的な歪みを生成できます。より大きな値を使用すると、制御点の周囲に広い影響範囲が生成されます。たとえば、これは「コアラの耳を引っ張る」例の繰り返しで、歪み重みに異なるパワーレベルが適用されています。

  magick koala.gif -virtual-pixel Black -define shepards:power=0.5 \
          -distort Shepards '30,11 20,11  48,29 58,29' \
          koala_ear_pull_pow0.5.png
  magick koala.gif -virtual-pixel Black -define shepards:power=1.0 \
          -distort Shepards '30,11 20,11  48,29 58,29' \
          koala_ear_pull_pow1.png

magick koala.gif -virtual-pixel Black \ -distort Shepards '30,11 20,11 48,29 58,29' \ koala_ear_pull.png magick koala.gif -virtual-pixel Black -define shepards:power=3.0 \ -distort Shepards '30,11 20,11 48,29 58,29' \ koala_ear_pull_pow3.png magick koala.gif -virtual-pixel Black -define shepards:power=8.0 \ -distort Shepards '30,11 20,11 48,29 58,29' \ koala_ear_pull_pow8.png
[IM Output]
オリジナル
& アクション
==> [IM Output]
パワー 0.5
[IM Output]
パワー 1.0
[IM Output]
パワー 2.0
(デフォルト)
[IM Output]
パワー 3.0
[IM Output]
パワー 8.0
上記のすべての画像結果は、まったく同じ制御点移動のセットを使用しています。唯一の違いは、それらの制御点の周りの影響範囲です。小さなパワーは、移動を制御点の近くの領域のみに「局所化」しますが、大きなパワーは制御点の周りの画像のより多くをドラッグします。非常に大きなパワーでは、このプルは、制御点の中間点に沿って画像を別々の領域に「引き裂く」傾向があります。さらに大きなパワーを使用することもでき、これにより、ソース制御点の周囲の領域が、宛先制御点の周囲の領域に単純に平行移動されます。これらの領域は「ボロノイ領域」のパターンを形成し、ソース画像の重複コピーを含めることができます。たとえば、ここでは、コアラの鼻(座標 28,24)の周りの領域を、六角形のパターンで7つの異なる領域にマッピングして、非常に効率的な方法で「昆虫の目」のような効果を生み出します。

  magick koala.gif -virtual-pixel Black -define shepards:power=25 \
          -distort Shepards '28,24 35,35 \
                      28,24 20,10   28,24 50,10 \
                      28,24 20,60   28,24 50,60 \
                      28,24 10,35   28,24 60,35'  koala_hexagonal.png
[IM Output]
シェパード歪みは、実際にはシェパード、スパースカラー演算子と同じ手法を使用して生成された変位マップ(宛先ピクセルをソース画像にマッピングする)と同等であり、これもこの同じパワーファクター定義の影響を受けることを覚えておいてください。

シェパード歪みの要約

シェパード歪みは非常に用途が広く、自由形式の方法であり、歪みを、与えられた点の動きまたは非動きによってマークされた領域に制限します。その歪みは、隣接する制御点間の距離に応じて局所化および制限されますが、すべての点は平均化されたグローバル効果を持ちます。この歪みは、線または領域によって駆動されるのではなく、点によって駆動されるため、異なるように移動する制御点が近すぎる位置にある場合、点の間が予期せずに膨らんだり、渦巻いたりする可能性があることを覚えておいてください。制御点の間で画像を渦巻かせたり、引き伸ばしたり、圧縮したりしますが、制御点の近くで画像を回転または拡大縮小しないように努めます。そして最後に、制御点から遠く離れた画像の全体的な平均平行移動を生成する可能性があります。ただし、制御点のブロックを移動して、一般的な相対位置を維持できる場合、一般的で非常に単純な点駆動の「画像モーフィング」技術を実装する方法が提供されます。Fred Weinhaus のスクリプト 'shapemorph2' は、シェパード歪みを使用して、優れた汎用「アニメーション画像モーフィング」プログラムを提供します。
内部的には、この歪みは、シェパードスパースカラーグラデーションジェネレーターを使用して、画像を歪ませるために2つの相対変位マップを作成するのと同等です。これが、Fred Weinhaus の元の "shapemorph" スクリプトの実行内容であり、歪み技術のソースでした。
シェパード歪みの使用に必要な計算の複雑さのため、IM は演算子のプラス "+distort" 形式を使用した「最適」の宛先ビューポートを提供しません。ただし、歪みビューポートオプションを使用して、より大きな出力画像を定義できます。
同様の理由で、エリアリサンプリングはオフになっています。そのため、極端な圧縮(2倍以上の倍率)の領域では、エイリアシング効果が表示される可能性があります。たとえば、最後の例の六角形パターンのエッジを参照してください。ただし、スーパーサンプリングを使用して、最終的な画像品質を向上させ、そのようなエイリアシング効果を低減できます。