【数値情報処理b】第4回の答え
課題
boats の画像を「右上角を中心に-20度回転したあと垂直反転」して表示するプログラムを作成しなさい。
for
で一つ一つの画素を処理し、imshift()
, imrotate()
, mirror()
を使わないこと。
「」の部分は人によって違う。
解答例
右上角を中心に回転には、「任意の座標中心の回転」を使う。 逆変換の計算式は以下の通り。
\begin{eqnarray} x_{0}&=&\left\{x_{1}-c_{x}(1-\cos\theta)-c_{y}\sin\theta\right\}\cos\theta+\left\{y_{1}+c_{x}\sin\theta-c_{y}(1-\cos\theta)\right\}\sin\theta\\ y_{0}&=&-\left\{x_{1}-c_{x}(1-\cos\theta)-c_{y}\sin\theta\right\}\sin\theta+\left\{y_{1}+c_{x}\sin\theta-c_{y}(1-\cos\theta)\right\}\cos\theta \end{eqnarray}
もしくは以下でも良い。
\begin{eqnarray} x_{0}&=&\left(x_{1}-c_{x}\right)\cos\theta+\left(y_{1}-c_{y}\right)\sin\theta+c_{x}\\ y_{0}&=&-\left(x_{1}-c_{x}\right)\sin\theta+\left(y_{1}-c_{y}\right)\cos\theta+c_{y} \end{eqnarray}
さらに、右上角を中心に回転のあとに垂直反転を行う必要がある。
- report4.R
- # レポート
- # 右上角を中心に-20度回転したあと垂直反転
- # 度からラジアンに変換する関数
- }
- im <- grayscale(boats)
- # cimg変数で処理すると遅いので配列で処理する
- # 回転角(度)
- theta <- -20
- # 回転の中心座標
- cx <- dim0[1]
- cy <- 0
- # 任意の座標中心の回転
- x2 <- x1 - cx * (1 - ct) - cy * st
- y2 <- y1 + cx * st - cy * (1 - ct)
- # もしくは x0 <- round( (x1 - cx) * ct + (y1 - cy) * st + cx)
- # もしくは y0 <- round(-(x1 - cx) * st + (y1 - cy) * ct + cy)
- g1[x1, y1, ,] <- g0[x0, y0, ,]
- }
- }
- # 移動量
- bx <- 0
- # 垂直反転と平行移動
- x0 <- x1 - bx
- g2[x1, y1, ,] <- g1[x0, y0, ,]
- }
- }
- # 配列→cimg変数
- im.rotate <- as.cimg(g2)
- # 同時に2枚並べるレイアウト
- # レイアウトを元に戻す
回転中心を変えるには 24,25 行目を以下のように変更する。
- 右下角を中心に回転の場合
cx <- dim0[1] cy <- dim0[2]
- 左下角を中心に回転の場合
cx <- 0 cy <- dim0[2]
垂直反転の後に回転の場合は、39行目と54行目を入れ替えたあとに 20-41 行目と 43-56 行目を入れ替える。