AREngine深度图优化之一基于最大/最小/平均值的补洞方法

我们都知道AREngine返回的深度图质量并不高,大概率是直接返回的tof深度图,跟ARCORE返回的深度图差距还是比较大的。在我们当前AR云渲染项目中,需要用到AREngine返回的深度图,这就需要提高深度图的质量。

所以就开始研究怎样优化AREngine的深度图的方法。本篇博客是对深度图进行补洞的常规方法。

基于最大/最小/平均值的补洞方法,无非就是在周边像素找到能够对候补像素进行补值的算法。如下图所示。

 

在opengl中,我们会查找周边的像素,找到最大/最小值,或者计算出所有像素的平均值,作为候补像素的值。注意的是,在我们算法中,主要是补“白点”像素,根据不同场景,你们可能有不同的判断。但是基本的算法都是想通的。

#version 320 es
#extension GL_OES_EGL_image_external_essl3: enable
precision highp float;
precision highp usampler2D;

#define ARCLOUD_MAX_DEPTH_MM 2000.0
#define FAR ARCLOUD_MAX_DEPTH_MM
#define NEAR 50.0

layout (binding = 0) uniform sampler2D inTexture;

float bias = 0.001;

vec4 encodeFloatRGBA(float v)
{
    float r = float((int(v)) & 0xFF);
    float g = float((int(v) >> 8) & 0xFF);
    return vec4(r / 255.0, g / 255.0, 0.0, 1.0);
}

float decodeFloatRGBA(vec4 enc)
{
    return enc.r  * 255.0 + enc.g * 256.0 * 255.0;
}

//opt == 1: max
//opt == 2: min
//opt == 3: +

//return x: 计算之后的值,y: 计算之后的个数
vec2 calOperator(float left, float right, int opt) {
    float ret = 0.0;
    float count = 0.0;
    switch (opt) {
        case 1:
        ret = max(left, right);
        count = 0.0;
        break;
        case 2:
        ret = min(left, right);
        count = 0.0;
        break;
        case 3:
        ret = left + right;
        count = 1.0;
        break;
    }

    return vec2(ret, count);
}

vec4 statisticalFilter(vec2 texCoords, int mode) {
    const int rad = 2;
    float sum = 0.0;
    int opt = 3;

    switch (mode) {
        case 1:
        sum = 1.0;
        opt = 1;
        break;
        case 2:
        sum = 1.0;
        opt = 2;
        break;
        case 3:
        sum = 0.0;
        opt = 3;
        break;
    }

    ivec2 size = ivec2(0);
    if (isSrcTexture) {
        size = textureSize(srcTexture, 0);
    } else {
        size = textureSize(inTexture, 0);
    }
    vec2 tex_offset = 1.0 / vec2(size);
    float result = 0.0;

    float curDepth = getDepth(texCoords);
    //如果像素不是为白点,则直接返回原始的深度值, FAR为我们的最大深度值,在AREngine中,设置4000mm比较好一点
    if (abs(curDepth - FAR) < bias) {
        for (int x = -rad; x <= rad; ++x)
        {
            for (int y = -rad; y <= rad; ++y)
            {
                if (x == 0 && y == 0) {
                    continue;
                }

                //超越边界的不做处理
                vec2 curUv = texCoords + vec2(x, y) * tex_offset;
                if (any(lessThan(curUv, vec2(0.0, 0.0)))) {
                    continue;
                }

                if (any(greaterThan(curUv, vec2(1.0, 1.0)))) {
                    continue;
                }

                float tempDepth = getDepth(curUv);

                //只寻找非白点的值
                if (abs(tempDepth - FAR) < bias) {
                    continue;
                }

                vec2 calResult = calOperator(result, tempDepth, opt);
                result = calResult.x;
                sum += calResult.y;
            }

            if (abs(result - 0.0) < 0.00001) {
                result = curDepth;
            }
        }
    } else {
        result = curDepth;
        sum = 1.0;
    }

    return encodeFloatRGBA(result / sum);
}

AREngine中如何获取深度图,请参考我的另外一篇文章: 华为AREngine根据深度图获取深度信息

我们看一下效果,有一定的效果。

最大值补洞效果:

最小值补洞效果:

平均值补洞效果:

参考文献:

https://github.com/intelligent-control-lab/Kinect_Smoothing

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XR风云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值