2009年01月22日
大学構内ストリートビュー計画 をちょっとがんばってみた結果。
Gestalt★彡氏発案の大学構内ストリートビュー計画。 ちなみにこっちに載ってるHandleってのはぼくのことです。 ちょっと試してみた感想。
追記に続く。
ストリートビュー的なことをするためにはまずは写真を用意しなければならないわけで。 この写真を用意する方法にはおおむね2つあると思います。
- 複数台の(普通の)カメラの映像を合成
- 全方位カメラで撮影
1.は安いカメラを使う、あるいは一台のカメラでがんばれば結構安くあがるけど、3Dな感じに見せる処理が大変・・・な気がする。
2.は処理が簡単だけど費用がかかる(全方位カメラは安くても10万円くらい)。
とりあえずどんな撮影を行うかは置いといて、写真をそれっぽく見せるプログラムを書いてみました。 とりあえずActionScript with Papervision3Dで。
画像を組み合わせる場合
とりあえずなにも考えずに8枚の写真を八方向に並べてみることに。
それっぽくはなるけれど、写真をうまくつなぎ合わせるのが大変。 あとぐるっと360度撮るだけじゃなくて、上下方向の写真も必要ですね。 でも、大学案内をする分には充分かもしれません。
実際のプログラムは・・・、拾ってきた写真で試してたもので、載せられません。申し訳ない。 こんどどっかで写真撮ってきます。 ソースコードは・・・あまりにも汚いので勘弁してください。
全方位カメラを使う場合
全方位カメラを使う場合は、球体のオブジェクトの内側にテクスチャとして写真を貼り付ければOK。 撮影した画像(円形。想像だけど・・・)を極座標変換で長方形にしたものを貼り付ければいい感じになります。
ソースコードはこんな感じ。 球形のオブジェクトにテクスチャ貼るだけです。 外側に貼ったテクスチャを内側からみる、みたいな感じなので、実際には画像を左右反転してから貼らないとダメですが、今回は特になにもやってません。 とりあえずどんな感じになるのかを見てみたかっただけなので。
package { import flash.display.*; import flash.events.*; import flash.net.*; import flash.ui.Keyboard; import org.papervision3d.cameras.*; import org.papervision3d.materials.*; import org.papervision3d.materials.special.*; import org.papervision3d.objects.primitives.*; import org.papervision3d.render.*; import org.papervision3d.scenes.*; import org.papervision3d.view.*; public class main extends Sprite { private var mScene :Scene3D; private var mViewport :Viewport3D; private var mCamera :Camera3D; private var mRenderer :BasicRenderEngine; private var mPlane :Sphere; public function main() { stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; stage.frameRate = 30; init(); } public function init() { // viewport mViewport = new Viewport3D(0, 0, true); mViewport.opaqueBackground = 0x000000; addChild(mViewport); // renderer mRenderer = new BasicRenderEngine; // camera mCamera = new Camera3D(); mCamera.z = 0; mCamera.focus = 300; mCamera.zoom = 1; mCamera.rotationX = 30; // scene mScene = new Scene3D(); // object var urlReq :URLRequest = new URLRequest('path/to/image'); // 全方位写真へのパス var bmp :Loader = new Loader(); bmp.load(urlReq); bmp.contentLoaderInfo.addEventListener(Event.INIT, function(evt :Event) :void { var pf :Sprite = new Sprite(); pf.addChild(bmp); var bmpData :BitmapData = new BitmapData(800, 400, true); // サイズは画像のサイズに合わせる bmpData.draw(pf); var bmpMaterial :BitmapMaterial = new BitmapMaterial(bmpData, true); bmpMaterial.doubleSided = true; mPlane = new Sphere(bmpMaterial, 2000, 36, 36); mScene.addChild(mPlane); }); stage.addEventListener(Event.ENTER_FRAME, function() :void { mRenderer.renderScene(mScene, mCamera, mViewport); }); stage.addEventListener(KeyboardEvent.KEY_DOWN, function(evt :KeyboardEvent) :void { if(evt.keyCode == Keyboard.UP) { mCamera.rotationX -= 3; } else if(evt.keyCode == Keyboard.DOWN) { mCamera.rotationX += 3; } else if(evt.keyCode == Keyboard.LEFT) { mCamera.rotationY -= 3; } else if(evt.keyCode == Keyboard.RIGHT) { mCamera.rotationY += 3; } }); } } }
自分で撮った写真を使ってないので実際に動くものは見せられないんですが・・・。 著作権フリーな全方位写真があれば教えてください。プログラムにのっけたものを公開します。 なかなかそれっぽくなります。 まさにストリートビュー。 ただ、うちの環境でCPU使用率が常に50%くらいになります。 ちょっと、重い。
ちなみに使う画像はこんなのや、こんなの。 写真さえ用意できれば、あとPCへの負荷を考えなければかなりいいです。
試してみて
結論として、やっぱりやるなら全方位カメラを使いたいですね。 その方が断然きれいですし。 負荷の問題さえクリアすればかなり行けるんじゃないかと思います。
ストリートビューなことを調べてみると、結構同じようなことやってる人がいるんですね。 これとか、これとか、これとか。 1番目のと2番目のはGoogle本家のを使ってるんでしょうか。 よく見てないのでわかりませんが。