OpenGL ES 图像基本处理:腐蚀、膨胀、边缘检测

共 6693字,需浏览 14分钟

 ·

2024-03-24 23:30

前文我们详细讲了图像锐化的基本原理,本文再介绍一下图像基本处理之腐蚀、膨胀和边缘检测,它们在图像处理和计算机视觉领域有着广泛的应用。

图像腐蚀(Image Erosion):用于缩小或消除图像中物体的边界。主要用于去除图像中的小细节、噪声或不规则物体。

e85626dcf88a1e58d46404b11f16405b.webp

实现图像腐蚀的片段着色器代码,基本原理就是寻找附近的最小 color 作为输出:

      precision highp float;
varying highp vec2 vTextureCoord;
uniform lowp sampler2D sTexture;
uniform highp vec2 inputSize;

void main() {
    vec2 uv = vTextureCoord;

    float step = 1.0;
    vec2  uvOffsets[25];
    float dx = step / inputSize.x;
    float dy = step / inputSize.y;

    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            uvOffsets[((i*5)+j)].x = (-2.0 * dx) + (float(i) * dx);
            uvOffsets[((i*5)+j)].y = (-2.0 * dy) + (float(j) * dy);
        }
    }

    vec4 result = vec4(1.0);
    for (int i = 0; i < 25; i++)
    {
        vec4 col = texture2D(sTexture, uv + uvOffsets[i]);
        result = min(result, col);
    }

    gl_FragColor = result;
}

图像腐蚀效果对比:

5afa3d7884af3a4c0c83800983de899a.webp

图像膨胀(Image Dilation):用于增大或突出图像中物体的边界。主要用于连接图像中的物体,填充小孔或缝隙,以及强调物体的边缘。

实现图像膨胀的片段着色器代码,基本原理就是寻找附近的最大 color 作为输出:

      precision highp float;
varying highp vec2 vTextureCoord;
uniform lowp sampler2D sTexture;
uniform highp vec2 inputSize;

void main() {
    vec2 uv = vTextureCoord;

    float step = 1.0;
    vec2  uvOffsets[25];
    float dx = step / inputSize.x;
    float dy = step / inputSize.y;

    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            uvOffsets[((i*5)+j)].x = (-2.0 * dx) + (float(i) * dx);
            uvOffsets[((i*5)+j)].y = (-2.0 * dy) + (float(j) * dy);
        }
    }

    vec4 result = vec4(0.0);
    for (int i = 0; i < 25; i++)
    {
        vec4 col = texture2D(sTexture, uv + uvOffsets[i]);
        result = max(result, col);
    }

    gl_FragColor = result;
}

图像膨胀效果对比:

dbb84a2506734c768f2522137f540928.webp

边缘检测(Edge Detection):用于识别图像中物体之间的边界。常用于目标检测、图像分割和计算机视觉任务。常见的边缘检测算法包括Sobel、Prewitt、Canny等。

实现图像边缘检测的片段着色器代码,代码基本上跟上节降到的锐化的实现方式一样,都是使用一个卷积核(高通滤波):

      precision highp float;
varying highp vec2 vTextureCoord;
uniform lowp sampler2D sTexture;
uniform highp vec2 inputSize;

void main() {
    vec2 uv = vTextureCoord;
    float step = 5.0;
    vec2  uvOffsets[9];
    float dx = step / inputSize.x;
    float dy = step / inputSize.y;

    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            uvOffsets[((i*5)+j)].x = (-1.0 * dx) + (float(i) * dx);
            uvOffsets[((i*5)+j)].y = (-1.0 * dy) + (float(j) * dy);
        }
    }

    vec4 sampleCols[9];

    for (int i = 0; i < 9; i++)
    {
        // 采样邻域的网格
        sampleCols[i] = texture2D(sTexture, uv + uvOffsets[i]);
    }

    // 锐化卷积核 3x3
    // -1 -1 -1
    // -1  8 -1
    // -1 -1 -1

    vec4 result = 8.0 * sampleCols[4];
    for (int i = 0; i < 9; i++)
    {
        if (i != 4)
        result -= sampleCols[i];
    }
    gl_FragColor = result;
}

边缘检测效果对比:

701a96e53420c8666ac7f087026deec5.webp

参考链接:
https://blog.csdn.net/weixin_44225182/article/details/101310131
https://blog.csdn.net/panda1234lee/article/details/52320832


-- END --


进技术交流群,扫码添加我的微信:Byte-Flow



获取相关资料和源码


推荐:

Android FFmpeg 实现带滤镜的微信小视频录制功能

全网最全的 Android 音视频和 OpenGL ES 干货,都在这了

一文掌握 YUV 图像的基本处理

抖音传送带特效是怎么实现的?

所有你想要的图片转场效果,都在这了

面试官:如何利用 Shader 实现 RGBA 到 NV21 图像格式转换?

我用 OpenGL ES 给小姐姐做了几个抖音滤镜


项目疑难问题解答、大厂内部推荐、面试指导、简历指导、代码指导、offer 选择建议、学习路线规划,可以点击找我一对一解答。

浏览 13
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报