本題に入る前に、必ず動画の
連絡
を見てください。
- X方向のスキュー
- Y方向のスキュー
- X方向のスキュー (OpenCV)
- Y方向のスキュー
(OpenCV)
※ 動画の解説では4番目の課題でできる2つの画像をClass Notebookに逆の順番で入れてしまっています。正しい順番で入れれば2番目の課題と同じような状態 (1枚目が右下がり、2枚目が左下がり) になります。
横、縦の幅が \(width, height\) の元画像と、その中にある点 \((x, y)\) は、
X方向に30°スキューさせるとこうなる。
元画像の範囲が収まるようにするには、出力画像の横幅を図の灰色の三角形の底辺の分、つまり \(height\times\tan(30)\) 広げる必要がある。
変形後の横位置(左端からの距離)、縦位置(上端からの距離) \((x', y')\) を元の画像の座標 \((x, y)\) で表すと
\(x' = x + y\tan(30)\)
\(y' = y\)
になる。
この変換は、行列を使って表すこともできる。
\(
\begin{pmatrix}
x'\\y'\\1
\end{pmatrix}
=
\begin{pmatrix}
1 & \tan(30) & 0\\
0 & 1 & 0\\
0 & 0 & 1
\end{pmatrix}
\begin{pmatrix}
x\\y\\1
\end{pmatrix}
\)
Xの負の方向にスキューさせた場合は、左側のスタート位置が灰色の三角形の底辺の分だけずれる。
\((x, y)\) にいた点の、変形後の座標は
\(x' = x + y\tan(-30) + height\left|\tan(-30)\right|\)
\(y' = y\)
になる (\(tan(-30)\) が負の値であることに注意)。
この変換を行列で表すとこのようになる。
\(
\begin{pmatrix}
x'\\y'\\1
\end{pmatrix}
=
\begin{pmatrix}
1 & \tan(-30) & height\left|\tan(-30)\right|\\
0 & 1 & 0\\
0 & 0 & 1
\end{pmatrix}
\begin{pmatrix}
x\\y\\1
\end{pmatrix}
\)
一般化すると、角度 \(a\) が正なら
\(
\begin{pmatrix}
x'\\y'\\1
\end{pmatrix}
=
\begin{pmatrix}
1 & \tan(a) & 0\\
0 & 1 & 0\\
0 & 0 & 1
\end{pmatrix}
\begin{pmatrix}
x\\y\\1
\end{pmatrix}
\)
角度 \(a\) が負なら
\(
\begin{pmatrix}
x'\\y'\\1
\end{pmatrix}
=
\begin{pmatrix}
1 & \tan(a) & height\left|\tan(a)\right|\\
0 & 1 & 0\\
0 & 0 & 1
\end{pmatrix}
\begin{pmatrix}
x\\y\\1
\end{pmatrix}
\)
のように書ける。
Y方向にスキューさせるときも考え方は同様。X方向の処理を
\(x \leftrightarrow y\)
\(width \leftrightarrow height\)
のように置き換えるだけ。変換を行列の形で書くと
正の角度 \(a\) だけY方向にスキューさせると
\(x' = x\)
\(y' = y+ x\tan(a)\)
で、行列の形で書くと
\(
\begin{pmatrix}
x'\\y'\\1
\end{pmatrix}
=
\begin{pmatrix}
1 & 0 & 0\\
\tan(a) & 1 & 0\\
0 & 0 & 1
\end{pmatrix}
\begin{pmatrix}
x\\y\\1
\end{pmatrix}
\)
負の角度 \(a\) だけY方向にスキューさせると
\(x' = x\)
\(y' = y+ x\tan(a) +width\left|\tan(a)\right|\)
で、行列の形で書くと
\(
\begin{pmatrix}
x'\\y'\\1
\end{pmatrix}
=
\begin{pmatrix}
1 & 0 & 0\\
\tan(a) & 1 & width\left|\tan(a)\right|\\
0 & 0 & 1
\end{pmatrix}
\begin{pmatrix}
x\\y\\1
\end{pmatrix}
\)
のようになる。