- ベストアンサー
透視投影した図形の法線ベクトルについて
- 透視投影した図形の法線ベクトルについて
- 透視投影した図形の平面の法線ベクトルを元の画像の100pixel分の長さで描く方法はありますか?
- 透視投影した図形の平面の法線ベクトルを描くための近似的な方法を探しています。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
> 面あるいは点が空間的にどう動いたかという情報があって投影点を計算するのではないのです。 > あくまで元の正面にあった面が、別の見え方になりそれを表す射影変換行列のみが手に入ったという状態なんです。 もう少し考えてみました。 仰る所の「射影変換行列」から「面あるいは点が空間的にどう動いたかという情報」(平面上の点以外に関する変換方法)を(ほぼ)再現するのは、(先の回答では不可能と断じてしまいましたが、いや)可能です。可能ですが大変です。 「射影変換行列」は、どんなものかは知りませんが、ともかく線形変換ではありえません。このため、「射影変換行列」に書いてある係数から、平面Sの位置、すなわち空間中での回転(α,β,γ)と平行移動(x0, y0, z0)を再現するには、なかなか複雑な連立非線形方程式を数値計算で解く必要があります。プログラムを作るのは簡単とは言えませんし、しかも、これだけでは決められないパラメータが1個残ります。それでもやるかどうか。(やると仰るなら、方程式をupしても良いです。) それよりは、できれば「面あるいは点が空間的にどう動いたかという情報」をなんとかナマで手に入れる算段をする方が合理的だと思うんですが。 ところで、ご質問の中で、「近似的な方法でも良い」と仰っている。どの程度の「近似的」を認めるかで話は全然違いますが、 (1) 平面S上の絵がカメラからかなり遠くにある(つまり、床面とカメラとの距離に比べて絵とカメラの距離が結構大きい)、 (2) 平面S上に任意に長方形を決めたとき、その各頂点が像のどこに来るか計算できる。 という状況だろうと思います。だとすれば、こんな手がありますので、ご検討下さい: 以下はカメラで得た画像(X,Y)上での操作です。 まず、長方形の像の対辺を延長して、それらの交点B1を見つけます。その交点は「消失点」です。2対の対辺を使って消失点B1, B2を得たら、これらを結ぶ直線が「(平面Sを無限に拡張した時にできる)水平線」です。 水平線から長方形の像の各頂点に垂線を下ろすと、この垂線は頂点上の法線をある程度近似しています。(カメラの向きに依存する誤差が出るのですが。) 垂線のひとつを決めて、その上に適当な内分点Pをひとつ取ります。このPはその頂点から生えている毛の先端、ということですので、短ければ誤差はあまり目立ちません。 消失点B1とPを結ぶ直線を描き、これが他の垂線と交わる交点を求めます。交点が平面Sより「上」にあれば、それが対応する頂点の毛の先端です。B2からも同じように直線を描けば、4つの頂点の毛の先が確定するでしょう。これらの毛先を結んだ四角形Rを描きます。 次に長方形の像の辺上の点Qについて、水平線から垂線を下ろします。これと、四角形Rの辺との交点が、Qの毛の先です。Qの毛の先と消失点とを結んだ直線と、四角形Rの辺とのもう一つの交点は、Qが乗っている辺の対辺上にある点の毛先です。この毛先に水平線から垂線を下ろして長方形の像の辺まで延長すると、その毛の根本が決まります。 辺上のいくつかの点についてこの操作を繰り返して行くと、長方形の像と四角形Rに格子が描かれます。すると、長方形の像上の格子点が毛の根本、四角形R上の格子点が毛先です。これで沢山の毛が生えました。 もとの長方形(像ではない)の辺上に等間隔で並ぶ点の像をQとすれば、毛は等間隔の格子点上から生えることになるので、見栄えが良いでしょう。 本当は、毛は根本より毛先の方がちょっとだけ広がって見える筈なのですが、上記の方法だと毛は全部平行になってしまいます。やっぱり法線は幾何学的にできるだけ正しいものである必要があるでしょうねえ。さもないと何でそんなもの描きたいのだか分からんわけですから。
その他の回答 (3)
- stomachman
- ベストアンサー率57% (1014/1775)
ANo.2へのコメントについてです。 > おそらく、私の説明が悪いために問題が正確に伝わっていない いや、問題の意味は分かっているつもりです。(ANo.1の最初の段落にどう理解したかを書いたので、違っている所があるなら具体的に指摘して下さい。)だから、stomachmanの説明が悪いんですね。 繰り返しになりますが、「平面射影行列」とは、ANo.1で説明した射影変換を、ある平面(画像のある平面)S上の点だけに限定して適用するための公式の形に変形したものにほかなりません。 たとえば簡単な例として、平面S上の直交座標系(u,v)が、 x = u y = v cosθ z = v sinθ + C となっている(つまり、カメラの光軸=z軸上でカメラからCだけ離れていて、θだけ傾いている平面だと)とすると、これらの関係を用いて射影変換X=x/z, Y=y/zのx,y,zを消去したもの、つまり X=u/(v sinθ+ C), Y=(v cosθ)/(v sinθ+ C) (あるいはこれをu,vについて解いたもの)が、仰るところの「平面射影行列」であるはず。平面上の点の位置を表すu,vは入っているけれども、平面から離れた点の位置を表す手段は消去されています。 ですから、「平面射影行列」を使ってなんとかしようとしても、平面S上以外の場所にある点がどこに写るかを計算するのは不可能ということです。実際、ANo.1へのコメントに > そこから伸びる点qの計算の仕方がわかりません とお書きなのが、その証拠じゃないですか? 画像上の点(u,v)から伸びる長さwの毛の先の座標はx,y,zでなら表せます。すなわち x = u y = v cosθ + w sinθ z = v sinθ - w cosθ + C です。しかし、「平面射影行列」にはwを入れるところがない。毛の先の像の位置(X,Y)を知るには、射影変換を「ある平面上の点だけに限定」した時点で捨ててしまった部分がどうしても必要なのですよ。だから、元の射影変換に戻るしかないのです。 おそらく、「解法が予想していたものと違う」というのがご不満なのでしょうが、それはしょうがないす。
- stomachman
- ベストアンサー率57% (1014/1775)
> 根元の点は平面射影行列を掛けることで計算できますが、そこから伸びる点qの計算の仕方がわかりませんでした。 絵はある平面S上にある点の集まり。その各点から法線ベクトルの線が生えている。これらの点についてNo.1の計算だけやれば全部終わり。 「平面射影行列」なんて使わない。捨てるんです。その「平面射影行列」というものは、「No.1の計算において、点が平面S上にあるという条件を追加して式を単純化したもの」に他ならないからです。(ほんとにそうなってるか、確かめてみれば?)
補足
おそらく、私の説明が悪いために問題が正確に伝わっていないように思います。平面射影行列すら使わないのであれば、定義している問題が異なると思います。 面あるいは点が空間的にどう動いたかという情報があって投影点を計算するのではないのです。 あくまで元の正面にあった面が、別の見え方になりそれを表す射影変換行列のみが手に入ったという状態なんです。 (画面上での投影⇒画面上での投影の関係性のみ。)
- stomachman
- ベストアンサー率57% (1014/1775)
「正面から見た画像」の表面に法線ベクトルの毛が生えているのを床面に敷いたものを、ピンホールカメラで撮った写真がどうなるか、ということでござんしょう。しかも、その写真を撮るスクリーン(フイルム面)はどうやら平面であるらしい。そういう話ですね。 ピンホールカメラのピンホールの位置を(0,0,0)とし、フィルム面をz=1の面だとしましょう。すると、空間中の位置p=(x,y,z)にあるものの像は、(0,0,0)と(x,y,z)を結ぶ直線と、フィルム面との交点(X,Y,1)にできる。(手前にあるもののかげに隠れて見えない、という効果はここでは考慮しません。)すると、図を描いてみれば明らかなように、X=x/z, Y=y/zという簡単な関係になっています。 さらに、空間中の勝手な2点pとqを決めたとき、p, qを結ぶ直線上にある任意の点rのフィルム面上での像Rは、点pの像Pと点qの像Qとを結ぶ直線上に来ることが、関係式X=x/z, Y=y/zから容易に証明できます。 従って、「正面から見た画像」の表面に生えているある一本の毛の根元の点pと先の点qがフィルム上のどこに像を結ぶか、を計算すれば出来上がりです。
補足
根元の点は平面射影行列を掛けることで計算できますが、そこから伸びる点qの計算の仕方がわかりませんでした。
お礼
私の質問が悪かったにも関わらず、さらなる回答をいただき、ありがとうございます。 消失点を用いる方法は眼から鱗でした。擬似的に使えそうな方法で、提示していただけて大変参考になりました。 ありがとうございます!