OK I think I managed to do this... well +/- as the equation:
Is just symbolical simplification (common in CV/DIP) not complete equation not uniquely determined... So its interpretation (and implementation) is not clear from it... However I managed to combine the missing stuff into something like this (GLSL):
//---------------------------------------------------------------------------
// Vertex
//---------------------------------------------------------------------------
#version 420 core
//---------------------------------------------------------------------------
layout(location=0) in vec4 vertex;
out vec2 pos; // screen position <-1,+1>
void main()
{
pos=vertex.xy;
gl_Position=vertex;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Fragment
//---------------------------------------------------------------------------
#version 420 core
//---------------------------------------------------------------------------
in vec2 pos; // screen position <-1,+1>
out vec4 gl_FragColor; // fragment output color
uniform sampler2D txr_rgb;
uniform sampler2D txr_zed0;
uniform sampler2D txr_zed1;
uniform sampler2D txr_zed2;
uniform sampler2D txr_zed3;
uniform sampler2D txr_zed4;
uniform float xs,ys; // texture resolution
uniform float r; // blur radius
//---------------------------------------------------------------------------
float G(float t)
{
return 0.0;
}
//---------------------------------------------------------------------------
void main()
{
vec2 p;
vec4 rgb;
const int m=5;
const float Th=0.0015;
float z[m],zed;
p=0.5*(pos+1.0); // p = pos position in texture
rgb=texture2D(txr_rgb ,p); // rgb color (just for view)
z[0]=texture2D(txr_zed0,p).r; // oldest 2 frames
z[1]=texture2D(txr_zed1,p).r;
if (abs(z[0]-z[1])>Th) // threshold depth change
{
int i;
float x,y,xx,yy,rr,dx,dy,w,w0;
// 2D spatial gauss blur of z0
rr=r*r;
w0=0.3780/pow(r,1.975);
z[0]=0.0;
for (dx=1.0/xs,x=-r,p.x=0.5+(pos.x*0.5)+(x*dx);x<=r;x++,p.x+=dx){ xx=x*x;
for (dy=1.0/ys,y=-r,p.y=0.5+(pos.y*0.5)+(y*dy);y<=r;y++,p.y+=dy){ yy=y*y;
if (xx+yy<=rr)
{
w=w0*exp((-xx-yy)/(2.0*rr));
z[0]+=texture2D(txr_zed0,p).r*w;
}}}
// fetch depths from up to m frames
z[2]=texture2D(txr_zed2,p).r;
z[3]=texture2D(txr_zed3,p).r;
z[4]=texture2D(txr_zed4,p).r;
// 1D temporal gauss blur
for (zed=0.0,i=1;i<=m;i++) zed+=exp(0.5*float(i*i)/float(m*m))*z[i-1];
zed/=2.506628274631000502415765284811*float(m);
}
else zed=z[0];
zed*=20.0; // debug view: emphasize depth so its color is visible
// gl_FragColor=rgb; // debug view: render RGB texture
gl_FragColor=vec4(zed,zed,zed,0.0); // render resulting depth texture
}
//---------------------------------------------------------------------------
I used this dataset for testing However the depth resolution is not very good...
Using garlic_7_1
dataset I got this result (emphasized depth):
The temporal depth is m
(hard coded) and spatial is r
(uniform). The last m
frames are passed in txr_zed0...txr_zed(m-1)
where txr_zed0
is the oldest one. The threshold Th
must be chosen so the algo select correct regions!!!
In order this to work properly You should replace txr_zed0
after applying this shader by its result (on CPU side or render to texture and then swap ids ...). Otherwise the spatial Gauss blurring will not be applied to older frames.
[edit1]
Here the preview (outputting red inside the if
instead of blurring) for Th=0.01;
As you can see it selects the edges ... So the change (just for chosing Th) is:
//---------------------------------------------------------------------------
// Fragment
//---------------------------------------------------------------------------
#version 420 core
//---------------------------------------------------------------------------
in vec2 pos; // screen position <-1,+1>
out vec4 gl_FragColor; // fragment output color
uniform sampler2D txr_rgb;
uniform sampler2D txr_zed0;
uniform sampler2D txr_zed1;
uniform sampler2D txr_zed2;
uniform sampler2D txr_zed3;
uniform sampler2D txr_zed4;
uniform float xs,ys; // texture resolution
uniform float r; // blur radius
//---------------------------------------------------------------------------
float G(float t)
{
return 0.0;
}
//---------------------------------------------------------------------------
void main()
{
vec2 p;
vec4 rgb;
const int m=5;
// const float Th=0.0015;
const float Th=0.01;
float z[m],zed;
p=0.5*(pos+1.0); // p = pos position in texture
rgb=texture2D(txr_rgb ,p); // rgb color (just for view)
z[0]=texture2D(txr_zed0,p).r; // oldest 2 frames
z[1]=texture2D(txr_zed1,p).r;
if (abs(z[0]-z[1])>Th) // threshold depth change
{
gl_FragColor=vec4(1.0,0.0,0.0,0.0); // debug output
return;
int i;
float x,y,xx,yy,rr,dx,dy,w,w0;
// 2D spatial gauss blur of z0
rr=r*r;
w0=0.3780/pow(r,1.975);
z[0]=0.0;
for (dx=1.0/xs,x=-r,p.x=0.5+(pos.x*0.5)+(x*dx);x<=r;x++,p.x+=dx){ xx=x*x;
for (dy=1.0/ys,y=-r,p.y=0.5+(pos.y*0.5)+(y*dy);y<=r;y++,p.y+=dy){ yy=y*y;
if (xx+yy<=rr)
{
w=w0*exp((-xx-yy)/(2.0*rr));
z[0]+=texture2D(txr_zed0,p).r*w;
}}}
// fetch depths from up to m frames
z[2]=texture2D(txr_zed2,p).r;
z[3]=texture2D(txr_zed3,p).r;
z[4]=texture2D(txr_zed4,p).r;
// 1D temporal gauss blur
w0=0.5/float(m*m);
for (zed=0.0,i=1;i<=m;i++) zed+=exp(w0*float(i*i))*z[i-1];
zed/=2.506628274631000502415765284811*float(m);
}
else zed=z[0];
zed*=40.0; // debug view: emphasize depth so its color is visible
// gl_FragColor=rgb; // debug view: render RGB texture
gl_FragColor=vec4(zed,zed,zed,0.0); // render resulting depth texture
}
//---------------------------------------------------------------------------