对深度图像进行时间滤波

时间:2020-11-12 03:39:51

标签: c# unity3d computer-vision shader fragment-shader

我正在阅读下面的论文,并且正在尝试实施它,但是似乎我还没有完全理解该论文。 https://vcg.informatik.uni-rostock.de/~malub/publications/2016_depthenhance/16_ARLS_depthenhancement.pdf

我已经计算了光流和深度图像的一些历史记录,并对历史记录样本进行了线性平均,如着色器代码所示。

我得到的是一张有孔的图像,但是原始图像没有孔。

enter image description here

当前过滤的图像

enter image description here

着色器实现:

Shader "Unlit/DepthFilter"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _PrevTex("_PrevTex", 2D) = "white" {}
        _CurrentDepth("Current Depth", 2D) = "white" {}
        _HistoryA("History A", 2D) = "white" {}
        _HistoryB("History B", 2D) = "white" {}
        _HistoryC("History C", 2D) = "white" {}

        _dataDelta("Data Delta", range(0, 256)) = 256
        _Lambda("Lambda", Range(0.0, 0.1)) = 0.015
        _Threshold("Threshold", Range(0.0, 10)) = 0.046
        _Scale("_Scale", Range(0.0, 10)) = 1.33

    }
        SubShader
        {
            Tags { "RenderType" = "Opaque" }
            LOD 100

            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag

                #include "UnityCG.cginc"

                struct appdata
                {
                    float4 vertex : POSITION;
                    float2 uv : TEXCOORD0;
                };

                struct v2f
                {
                    float2 uv : TEXCOORD0;
                    float4 vertex : SV_POSITION;
                };

                sampler2D _MainTex;
                sampler2D _PrevTex;
                float4 _MainTex_TexelSize;
                sampler2D _CurrentDepth;
                sampler2D _HistoryA;
                sampler2D _HistoryB;
                sampler2D _HistoryC;
                float     _dataDelta;
                float _Scale, _Lambda, _Threshold;
                float4 gradient(sampler2D tex, float2 uv, float2 offset)
                {
                    return (tex2D(tex, uv + offset)) - (tex2D(tex, uv - offset));
                }

                v2f vert(appdata v)
                {
                    v2f o;
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    o.uv = v.uv;
                    return o;
                }

                fixed4 frag(v2f i) : SV_Target
                {


                    float2 uv = i.uv;
                    float4 current = tex2D(_MainTex, uv);
                    float4 prev = tex2D(_PrevTex, uv);
                     
                    float2 dx = float2(_MainTex_TexelSize.x, 0);
                    float2 dy = float2(0, _MainTex_TexelSize.y);

                    float4 diff = current - prev;

                    float4 gx = gradient(_PrevTex, uv, dx) + gradient(_MainTex, uv, dx);
                    float4 gy = gradient(_PrevTex, uv, dy) + gradient(_MainTex, uv, dy);

                    float4 gmag = sqrt(gx * gx + gy * gy + float4(_Lambda, _Lambda, _Lambda, _Lambda));
                    float4 invGmag = 1.0 / gmag;
                    float4 vx = diff * (gx * invGmag);
                    float4 vy = diff * (gy * invGmag);

                    float2 flow = float2(0, 0);
                    const float inv3 = 0.33333;
                    flow.x = -(vx.x + vx.y + vx.z) * inv3;
                    flow.y = -(vy.x + vy.y + vy.z) * inv3;

                    float w = length(flow);
                    float nw = (w - _Threshold) / (1.0 - _Threshold);
                    flow = lerp(float2(0, 0), normalize(flow) * nw * _Scale, step(_Threshold, w));
                    
                    float2 curr = tex2D(_CurrentDepth, i.uv).xy;

                    float2 last_depth_frame_1 = tex2D(_HistoryA, i.uv).xy;
                    float2 last_depth_frame_2 = tex2D(_HistoryB, i.uv).xy;
                    float2 last_depth_frame_3 = tex2D(_HistoryC, i.uv).xy;

                    float2 last_depth_avg = (last_depth_frame_1 + last_depth_frame_2 + last_depth_frame_3) / 3.0;

                    float2 average_at_pixel;
                    average_at_pixel.x = curr.x + last_depth_avg.x - flow.x;
                    average_at_pixel.y = curr.y + last_depth_avg.y - flow.y;
                    fixed c = average_at_pixel;
                    //float4 velocity = float4(flow, 0,1);
                    //return float4(abs(velocity.xy), 0, 1);
                    return c;


                }
                ENDCG
            }
        }
}

0 个答案:

没有答案