実現したいこと
点群データを集めるためのシミュレーション環境を作る目的で最近Unityを勉強し始めた者です.今やりたいことは深度を線形化して深度画像として保存することです.
前提
以前質問させていただいたときの回答(https://teratail.com/questions/6wf3dt1lovwv1g)
を参考にし,深度バッファをRenderTextureに読み込み保存することができました.
得られたカラー画像と深度画像をPythonのopen3d(https://www.open3d.org/docs/release/tutorial/geometry/rgbd_image.html)
で点群に変換したところ,思い通りの点群を得ることができませんでした.
調べるとUnityのデプスバッファは非線形な値ということが分かり,これが思い通りの点群取得を防いでいると考えています.深度を線形にする方法としてシェーダ上で_CameraDepthTextureを用いて深度を取得した後にLinear01Depth,LinearEyeDepthなどの関数で線形化する方法があると分かり,次のサイト(https://light11.hatenadiary.com/entry/2018/05/08/012149)
に載っているコードで試したところ深度画像が得られず真っ白になってしまいました.
深度を線形化して深度画像として保存する方法・ノウハウなど知っている方がいましたら教えていただきたいです.よろしくお願いします!
深度画像とカラー画像を保存するために使ったコード
c#
1using UnityEngine;2using System.Collections;3using System.IO;4 5public class PreserveRenderTexture: MonoBehaviour 6{7 [SerializeField]8 public RenderTexture RenderTextureRef;9 [SerializeField]10 public RenderTexture RenderTextureCol;11 12 // Use this for initialization13 void Start()14 {15 16 }17 18 // Update is called once per frame19 void Update()20 {21 if (Input.GetKeyDown(KeyCode.Space))22 {23 // 深度画像を保存24 savePng();25 Debug.Log("Start savePng()");26 // カラー画像を保存27 SaveRenderTextureToPNG(RenderTextureCol, "screenshot.png");28 Debug.Log("Start SaveRenderTextureToPNG");29 30 }31 }32 33 void savePng()34 {35 Texture2D tex = new Texture2D(RenderTextureRef.width, RenderTextureRef.height, TextureFormat.RGB24, false);36 37 // 現在のレンダーターゲットを覚えておく38 RenderTexture currentTarget = RenderTexture.active;39 40 // texと同サイズのRenderTextureを用意する41 RenderTexture depthTexture = RenderTexture.GetTemporary(RenderTextureRef.width, RenderTextureRef.height);42 43 // 深度をカラーバッファ上にレンダリングするためのマテリアルを作る44 Material blitMaterial = new Material(Shader.Find("Unlit/MyUnlit"));45 46 // RenderTextureRefをdepthTexture上にレンダリングする47 Graphics.Blit(RenderTextureRef, depthTexture, blitMaterial);48 49 // Blitによって現在のレンダーターゲットはdepthTextureに切り替わっているので、その内容をtexに読み取る50 tex.ReadPixels(new Rect(0, 0, RenderTextureRef.width, RenderTextureRef.height), 0, 0);51 tex.Apply();52 53 // レンダーターゲットを元に戻す54 RenderTexture.active = currentTarget;55 56 // depthTexture、blitMaterialはもう不要なので削除する57 RenderTexture.ReleaseTemporary(depthTexture);58 Object.Destroy(blitMaterial);59 60 // Encode texture into PNG61 byte[] bytes = tex.EncodeToPNG();62 Object.Destroy(tex);63 64 //Write to a file in the project folder65 File.WriteAllBytes(Application.dataPath + "/../DepthRenderTexture_0125.png", bytes);66 67 }68 69 void SaveRenderTextureToPNG(RenderTexture rt, string filePath)70 {71 // アクティブなレンダリングテクスチャを設定72 RenderTexture.active = rt;73 74 // Texture2Dを作成してデータを読み込む75 Texture2D screenshot = new Texture2D(rt.width, rt.height, TextureFormat.RGB24, false);76 screenshot.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);77 screenshot.Apply();78 79 // 画像をバイトデータに変換80 byte[] bytes = screenshot.EncodeToPNG();81 82 // ファイルに保存83 System.IO.File.WriteAllBytes(filePath, bytes);84 85 // アクティブなレンダリングテクスチャをnullに設定86 RenderTexture.active = null;87 }88 89 90}
保存された深度画像とカラー画像

open3dで作成したRGBD画像と点群



0 コメント