2

以下の2つの画像(それぞれ元の画像と変換された画像)について考えてみます。3つの青い正方形(マーカー)は方向付けに使用されます。

オリジナル 変身

元の画像:

  • 私たちは幅、高さを知っています
  • 3つのマーカーすべての(x、y)座標がわかっています。

変換された画像:

  • 3つのマーカーすべての(x、y)座標を検出できます。
  • その結果、回転角、(x、y)平行移動の量、および(x、y)スケーリング係数を計算できます。

ここで、System.Drawing.Graphicsオブジェクトを使用して、RotateTransform、TranslateTransform、およびScaleTransformを実行します。問題は、結果の画像が元の画像のようになることは決してないということです。

スタックオーバーフローで、変換を適用する順序は重要ではないと言われましたが、私の観察は異なります。以下は、元の画像を生成し、いくつかの変換を導入した後、新しいキャンバスにそれを描画しようとするコードです。変換の順序を変更して、さまざまな結果を表示できます。

public static void GenerateImages ()
{
    int width = 200;
    int height = 200;
    string filename = "";
    System.Drawing.Bitmap original = null; // Original image.
    System.Drawing.Bitmap transformed = null; // Transformed image.
    System.Drawing.Graphics graphics = null; // Drawing context.

    // Generate original image.
    original = new System.Drawing.Bitmap(width, height);
    graphics = System.Drawing.Graphics.FromImage(original);
    graphics.Clear(System.Drawing.Color.MintCream);
    graphics.DrawRectangle(System.Drawing.Pens.Red, 0, 0, original.Width - 1, original.Height - 1);
    graphics.FillRectangle(System.Drawing.Brushes.Blue, 10, 10, 20, 20);
    graphics.FillRectangle(System.Drawing.Brushes.Blue, original.Width - 31, 10, 20, 20);
    graphics.FillRectangle(System.Drawing.Brushes.Blue, original.Width - 31, original.Height - 31, 20, 20);
    filename = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "Original.png");
    original.Save(filename, System.Drawing.Imaging.ImageFormat.Png);
    graphics.Dispose();

    // Generate transformed images.
    transformed = new System.Drawing.Bitmap(width, height);
    graphics = System.Drawing.Graphics.FromImage(transformed);
    graphics.Clear(System.Drawing.Color.LightBlue);
    graphics.ScaleTransform(0.5F, 0.7F); // Add arbitrary transformation.
    graphics.RotateTransform(8); // Add arbitrary transformation.
    graphics.TranslateTransform(100, 50); // Add arbitrary transformation.
    graphics.DrawImage(original, 0, 0);
    filename = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "Transformed.png");
    transformed.Save(filename, System.Drawing.Imaging.ImageFormat.Png);
    graphics.Dispose();
    transformed.Dispose();

    original.Dispose();

    System.Diagnostics.Process.Start(filename);
}

ここで2つの潜在的な問題を見ることができます。

  • 変換は次々に適用されるため、最初に計算された値は役に立たなくなります。
  • グラフィックスオブジェクトは、(0、0)座標で回転を適用しますが、別のことを行う必要があります。何がわからない。
4

1 に答える 1

3

ここここ、およびここから私が理解していることから、Graphics.Drawing変換は、変換を適用する順序で行列を乗算することによって実行されます。

整数の場合、a * b * c = b * a * c

ただし、マトリックスを使用すると、ABCがBACと等しくなることはほとんどありません。

したがって、行列の乗算は可換ではないため、変換の順序は重要であるように見えます。

言い換えれば、私があなたの写真に次のことをすると、次のようになります。

ケース1:

  • 翻訳(100,50)
  • スケール(0.5,0.7)

写真は、左上隅が(100,50)、右下隅が(200,190)になります。

ケース2:

  • スケール(0.5,0.7)
  • 翻訳(100,50)

写真は、左上隅が(50,35)、右下隅が(150,174)になります。

これは、最初にスケーリングしてから変換することにより、スケーリングによって変換量もスケーリングされることを意味します。そのため、2つの場合、画像は左上隅で(50,35)になり、変換されたXの半分になります。および翻訳されたYの.7。

于 2012-08-27T07:04:18.690 に答える