透視変換を使用して画像を傾ける
-
20-09-2019 - |
質問
解決
これを行うためのより良い方法は、 逆マッピング。
要するに、画像を「ワープ」したいのですよね?これは、ソース画像内のすべてのピクセルが事前定義された点に移動することを意味します。事前定義は、回転、拡大縮小、平行移動、剪断などの方法を示す変換行列です。本質的に何らかの座標を取得している画像 (x,y)
画像上で「OK、このピクセルの新しい位置は (f(x),g(y))
.
それは本質的に「ワーピング」が行うことです。
さて、画像の拡大縮小について考えてみましょう...たとえば、サイズが10倍になります。つまり、ピクセルは (1,1)
のピクセルになります (10,10)
- そして次のピクセル、 (1,2)
ピクセルになります (10,20)
新しいイメージで。しかし、これを続けると、ピクセルの値がなくなり、 (13,13)
なぜなら、 (1.3,1.3)
は元の画像では定義されていないため、新しい画像にはたくさんの穴ができます。新しい画像の周囲の 4 つのピクセルを使用してその値を補間する必要があります。 (10,10) , (10,20), (20,10), (200,2)
- これは呼ばれます 双一次補間.
しかし、ここに別の問題があります。変換が単純なスケーリングではなく、(投稿したサンプル画像のように)アフィンであったとします。 (1,1)
のようなものになります (2.34,4.21)
次に、出力画像でそれらを丸める必要があります (2,4)
そして それから 穴を埋めるには新しい画像に対して双一次補間を行うか、より複雑な補間を行う必要があります。面倒ですよね?
さて、そこには とんでもない 補間から抜け出すには、双線形補間を行うだけで済みます。 一度. 。どうやって?単純、 逆マッピング。
ソース イメージが新しいイメージに移行すると考えるのではなく、新しいイメージのデータがソース イメージのどこから取得されるかを考えてください。それで、 (1,1)
新しい画像は、ソース画像の逆マッピングから取得されます。たとえば、 (3.4, 2.1)
次に、ソース画像に対して双一次補間を実行して、対応する値を見つけます。
変換行列
では、アフィン変換の変換行列はどのように定義すればよいでしょうか? このウェブサイト 回転やせん断などのさまざまな変換マトリックスを合成することでそれを行う方法を示します。
変換:
合成:
最終的な行列は、各行列を順番に合成することで実現できます。 反転 逆マッピングを取得するために使用します。これを使用して、ソース画像内のピクセルの位置を計算し、補間します。
他のヒント
あなたは、ホイールを再発明しのように感じるOpenCVのライブラリをチェックアウトしていない場合。これは、透視変換を含む多くの有用な画像処理機能を実現します。私は非常に簡単にこのタスクを達成するために使用しました cvWarpPerspective にチェックしてください。
KennyTM がコメントしたように、すべてのピクセルに行列を乗算して得られる線形マッピングであるアフィン変換が必要なだけです M そして結果を翻訳ベクトルに追加します V. 。単純な数学です
end_pixel_position = M*start_pixel_position + V
どこ M 回転やスケーリングなどの単純な変換の組み合わせです。 V は、固定係数をすべてのピクセルに追加することで画像のすべての点を変換するベクトルです。
たとえば、画像を回転したい場合は、回転行列を次のように定義できます。
| cos(a) -sin(a) |
M = | |
| sin(a) cos(a) |
どこ a
画像を回転する角度です。
スケーリングでは次の形式の行列が使用されます。
| s1 0 |
M = | |
| 0 s2 |
どこ s1
そして s2
は両方の軸のスケーリング係数です。
翻訳するにはベクトルを用意するだけです V:
| t1 |
V = | |
| t2 |
それは追加します t1
そして t2
ピクセル座標に変換します。
次に、単一の変換で行列を結合します。たとえば、スケーリング、回転、平行移動のいずれかを行う場合、次のような結果になります。
| x2 | | x1 |
| | = M1 * M2 * | | + T
| y2 | | y1 |
どこ:
x1
そしてy1
は変換を適用する前のピクセル座標です。x2
そしてy2
は変換後のピクセルです。M1
そしてM2
スケーリングと回転に使用される行列です (覚えて: 行列の合成は可換ではありません。いつものM1 * M2 * Vect != M2 * M1 * Vect
),T
すべてのピクセルを変換するために使用される変換ベクトルです。