実現したいこと
点群データを集めるためのシミュレーション環境を作る目的で最近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 initialization 13 void Start() 14 { 15 16 } 17 18 // Update is called once per frame 19 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 PNG 61 byte[] bytes = tex.EncodeToPNG(); 62 Object.Destroy(tex); 63 64 //Write to a file in the project folder 65 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}

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2024/01/26 05:46