一、图像腐蚀(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
- 边缘检测效果对比: