OpenGL ES之深入解析图像的腐蚀、膨胀、边缘检测处理

时间:2024-10-05 18:17:30

一、图像腐蚀(Image Erosion)

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

在这里插入图片描述

  • 实现图像腐蚀的片段着色器代码,基本原理就是寻找附近的最小 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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 图像腐蚀效果对比:

在这里插入图片描述

二、图像膨胀(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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 图像膨胀效果对比:

在这里插入图片描述

三、边缘检测(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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 边缘检测效果对比:

在这里插入图片描述