A=(aij)を
DIM A(4,4)
により定義された4行4列の行列(A(i,j)=aij)とするとき,絵定義pict_aを
DRAW pict_a WITH A
で描くと,
点( x,y )を行列演算
( x' y' z' w' ) = ( x y 0 1 ) |
|
により定まる点(x'/w', y'/w')に対応させる図形変形が行われる。
この変形は射影変換である。
視点の高さを1.5mとして,10m先の地平面に描かれた図形がその地点で垂直に描かれているように見えるようにしたい。
10m先に垂直に立つ平面上の座標を(x,y),10m先から地平面に座標(x',y')を考える。ただし,xの正の向きを水平方向,yの正の向きを鉛直方向,x'の正の向きをxの正の向きと同じ,y'の正の向きを視点から遠ざかる方向とする。
このとき,10+y':y'=1.5:y となるので,
y'= | 10y |
1.5−y |
また,x:x'=10:10+y' となるので,上の結果も利用して,
x'= | 1.5x |
1.5−y |
したがって,この変換は,
A = |
|
が定める射影変換である。
この変換は,次のようなプログラムで実行できる。
(1)図形を変換して描く
100 SET WINDOW -20,20,0,40 110 DRAW grid0 ! 1升=1m×1m 120 DIM m(4,4) ! 変換を行列で指定する。 130 DATA 1.5, 0, 0, 0 140 DATA 0, 10, 0, -1 150 DATA 0, 0, 0, 0 160 DATA 0, 0, 0, 1.5 170 MAT READ m 180 DRAW HalfHouse WITH m ! 行列を用いて変換して描く 190 PICTURE HalfHouse 200 DRAW house WITH SCALE(0.5) 210 END PICTURE 220 PICTURE House 230 SET AREA COLOR 15 240 PLOT AREA: 0,1; 0,0; 2,0; 2,1 ! 壁 250 SET AREA COLOR 2 260 PLOT AREA: -0.6,1; 2.6,1; 2,2; 0,2 ! 屋根 270 SET AREA COLOR 10 280 PLOT AREA: 0.1,0; 0.1,0.8; 0.5,0.8; 0.5,0 ! ドア 290 SET AREA COLOR 5 300 PLOT AREA: 1.4,0.4; 1.9,0.4; 1.9,0.8; 1.4,0.8 ! 窓 310 SET AREA COLOR 12 320 PLOT AREA: 1.7,2; 1.7,2.3; 1.5,2.3; 1.5,2 ! 煙突 330 END PICTURE 340 END
(2)画像を変換する
ここでは,文字を画像として扱い,変換対象としている。
なお,このプログラムにはVer. 7.4.2以降が必要。
100 SET WINDOW -10,10,0,20 110 DRAW grid0 ! 1升=1m×1m 120 DIM m(4,4) ! 変換を行列で指定する。 130 DATA 1.5, 0, 0, 0 140 DATA 0, 10, 0, -1 150 DATA 0, 0, 0, 0 160 DATA 0, 0, 0, 1.5 170 MAT READ m 180 DRAW pict1 WITH m ! 行列を用いて変換して描く 190 PICTURE pict1 200 SET TEXT HEIGHT 0.8 210 PLOT TEXT ,AT -1,0:"東京" ! 変換対象画像として文字を描く 220 END PICTURE 230 END
バージョンが古い場合は,次のプログラムを用いる。
100 SET COLOR MODE "NATIVE" !24ビットの色が使えるようにする 110 SET bitmap SIZE 801,801 120 SET WINDOW -2,2,0,4 130 DIM p(400,200) !縦1m,横2mの範囲を取り込める大きさの配列 140 SET TEXT HEIGHT 0.8 150 SET TEXT FONT "MS 明朝",0 160 PLOT TEXT ,AT -1,0:"東京" ! 変換対象画像として文字を描く 170 ASK PIXEL ARRAY (-1,1) p 180 CLEAR 190 SET WINDOW -10,10,0,20 ! 座標系を再設定 200 DIM m(4,4) ! 変換を行列で指定する。 210 DATA 1.5, 0, 0, 0 220 DATA 0, 10, 0, -1 230 DATA 0, 0, 0, 0 240 DATA 0, 0, 0, 1.5 250 MAT READ m 260 DRAW pict1 WITH m ! 行列を用いて変換して描く 270 DRAW grid0 ! 1升=1m×1m 280 PICTURE pict1 290 MAT PLOT CELLS, IN -1, 1 ; 1 , 0 : p 300 END PICTURE 310 END
遠方を眺めると遠方ほど小さく見える。これは,例1と逆の関係である。
視点の高さを1.5mとして,0.5m先に地平面に垂直に置かれたスクリーンに見えたとおりに写しとったとするとき,原点をスクリーン中央の地平面との接点に置くと,地平面上の点(x,y)は,次式で定まるスクリーン上の点(x',y')に写る。
y'= | 1.5y | = | (1.5/0.5)y |
0.5+y | 1+y/0.5 |
x'= | 0.5x | = | x |
0.5+y | 1+y/0.5 |
したがって,この変換(x, y)→(x', y')は,
A = |
|
が定める射影変換である。
この変換は,次のようなプログラムで実行できる。
なお,このプログラムの実行にはVer.7.4.2以降が必要。
100 DIM a(4,4) 110 DATA 0.5, 0, 0, 0 120 DATA 0, 1.5, 0, 1 130 DATA 0, 0, 0, 0 140 DATA 0, 0, 0, 0.5 150 MAT READ a 160 SET WINDOW -1,1,0,2 170 DRAW grid0 ! 1升=1m×1m 180 DRAW pict1 WITH a ! 行列を用いて変換して描く 190 PICTURE pict1 200 SET TEXT HEIGHT 0.8 210 PLOT TEXT ,AT -1,0:"東京" ! 変換対象画像として文字を描く 220 END PICTURE 230 END
バージョンが古い場合は,次のプログラムを用いる。
100 SET COLOR MODE "NATIVE" ! 24ビットの色(true color)が使えるようにする 110 SET bitmap SIZE 801,801 120 SET WINDOW -2,2,0,4 130 DIM p(400,200) ! 縦1m,横2mの範囲を取り込める大きさの配列 140 SET TEXT HEIGHT 0.8 150 SET TEXT FONT "MS 明朝",0 160 PLOT TEXT ,AT -1,0:"東京" ! 変換対象画像として文字を描く 170 ASK PIXEL ARRAY (-1,1) p 180 CLEAR 190 DIM m(4,4) ! 変換を行列で指定する。 200 DATA 0.5, 0, 0, 0 210 DATA 0, 1.5, 0, 1 220 DATA 0, 0, 0, 0 230 DATA 0, 0, 0, 0.5 240 MAT READ m 250 DRAW pict1 WITH m ! 行列を用いて変換して描く 260 DRAW grid0 ! 1升=1m×1m 270 PICTURE pict1 280 MAT PLOT CELLS, IN -1, 1 ; 1 , 0 : p 290 END PICTURE 300 END
地平面に格子を描いてみると,この変換の性質がさらによく見えてくる。
100 SET WINDOW -1,1,0,2 110 DIM m(4,4) ! 変換を行列で指定する。 120 DATA 0.5, 0, 0, 0 130 DATA 0, 1.5, 0, 1 140 DATA 0, 0, 0, 0 150 DATA 0, 0, 0, 0.5 160 MAT READ m 170 DRAW pict1 WITH m ! 行列を用いて変換して描く 180 PICTURE pict1 190 FOR y=0 TO 10 200 PLOT LINES:-100,y; 100,y 210 NEXT y 220 FOR x=-5 TO 5 230 PLOT LINES:x,0;x,1000 240 NEXT x 250 END PICTURE 260 END
次のプログラムは格子を斜め45度と-45度に描いている。
100 SET WINDOW -1,1,0,2 110 DIM m(4,4) ! 変換を行列で指定する。 120 DATA 0.5, 0, 0, 0 130 DATA 0, 1.5, 0, 1 140 DATA 0, 0, 0, 0 150 DATA 0, 0, 0, 0.5 160 MAT READ m 170 DRAW pict1 WITH m ! 行列を用いて変換して描く 180 PICTURE pict1 190 FOR x=-10 TO 10 200 PLOT LINES:x,0; 50+x,50 210 NEXT x 220 FOR x=-10 TO 10 230 PLOT LINES:x,0;-50+x,50 240 NEXT x 250 END PICTURE 260 END
垂直な壁面を仰角θで見上げるように撮影した写真画像を仰角なしで撮影したように修正することを考える。
図のA点から仰角θで撮影された写真画像は,図の太線に存在したかのように写る。ただし,この図は真横から見た図である。
写真画像で水平面をx軸とし,縦方向をy軸とする座標を考える。また,本来の壁面にも同様に水平との交線をx軸,垂直方向をy軸とする座標を考える。
仮想的な画像面上の点P(x,y)の座標から本来の点P'(x',y')の座標を求めるための変換式を作成したい。
y座標は,真横から見た図を利用して,AO=dとおくと,
y':y cosθ=OP':QP=AO:AQ=d:d−y sinθ=1:1−y(sinθ/d) より
y'= | y cosθ |
1−y (sinθ/d) |
x座標は,真上から見た図を用いて,
x':x=AO:AQ=d:d−y sinθから,
x'= | x |
1−y (sinθ/d) |
したがって,この変換は,
A = |
|
が定める射影変換である。
dは,垂直方向の画角の半分をα(=∠BAH),画像の高さをb(=BC)とすると,
AH tanα=b/2,d cosθ=AH より
d= | b | 1 |
2 | cosθ tanα |
と求まる。
さらに,OH=cとすると,c=d sinθ 。
この変換は,次のようなプログラムで実行できる。
元画像の横幅をa,高さをbとして,水平線がx軸となるように座標系を設定している。
100 OPTION ARITHMETIC NATIVE 110 OPTION ANGLE DEGREES 120 LET t=16 ! 仰角 130 LET v=33 ! 垂直方向画角の半分 140 SET COLOR MODE "NATIVE" ! 24ビットの色(true color)が使えるようにする。 150 GLOAD "tokeidai.JPG" 160 ASK PIXEL SIZE (0,0; 1,1) a,b ! 図の縦横の長さ(ピクセル単位)を調べる 170 DIM p(a,b) ! 図の大きさに対応する配列要素を用意する。 180 ASK PIXEL ARRAY (0,1) p ! 図の各点の色情報を配列に格納する。 190 SET BITMAP SIZE 401,401 ! ウィンドウの大きさを変更 200 CLEAR ! 図を消去 210 SET WINDOW -200, 200, -90, 310 ! 座標系を再設定 220 DRAW grid(100,100) ! 座標軸を描く 230 LET d=b/2/TAN(v)/COS(t) 240 LET c=d*SIN(t) 250 DIM m(4,4) ! 変換を行列で指定する。 260 MAT m=IDN 270 LET m(2,2)=COS(t) 280 LET m(2,4)=-SIN(t)/d 290 DRAW pict1 WITH m ! 行列を用いて変換して描く 300 PICTURE pict1 310 MAT PLOT CELLS, IN -a/2 + 1, c+b/2 ; a/2 , c-b/2 + 1 : p 320 END PICTURE 330 END
元画像(札幌時計台) 変換後
謝辞 元画像は,こちらからいただきました。