OpenGL ES 圖像基本處理:腐蝕、膨脹、邊緣檢測
前文我們詳細講了圖像銳化的基本原理,本文再介紹一下圖像基本處理之腐蝕、膨脹和邊緣檢測,它們在圖像處理和計算機視覺領(lǐng)域有著廣泛的應(yīng)用。
圖像腐蝕(Image Erosion):用于縮小或消除圖像中物體的邊界。主要用于去除圖像中的小細節(jié)、噪聲或不規(guī)則物體。

實現(xiàn)圖像腐蝕的片段著色器代碼,基本原理就是尋找附近的最小 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;
}
圖像腐蝕效果對比:

圖像膨脹(Image Dilation):用于增大或突出圖像中物體的邊界。主要用于連接圖像中的物體,填充小孔或縫隙,以及強調(diào)物體的邊緣。
實現(xiàn)圖像膨脹的片段著色器代碼,基本原理就是尋找附近的最大 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;
}
圖像膨脹效果對比:

邊緣檢測(Edge Detection):用于識別圖像中物體之間的邊界。常用于目標檢測、圖像分割和計算機視覺任務(wù)。常見的邊緣檢測算法包括Sobel、Prewitt、Canny等。
實現(xiàn)圖像邊緣檢測的片段著色器代碼,代碼基本上跟上節(jié)降到的銳化的實現(xiàn)方式一樣,都是使用一個卷積核(高通濾波):
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++)
{
// 采樣鄰域的網(wǎng)格
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;
}
邊緣檢測效果對比:

參考鏈接:
https://blog.csdn.net/weixin_44225182/article/details/101310131
https://blog.csdn.net/panda1234lee/article/details/52320832
-- END --
進技術(shù)交流群,掃碼添加我的微信:Byte-Flow
獲取相關(guān)資料和源碼
推薦:
Android FFmpeg 實現(xiàn)帶濾鏡的微信小視頻錄制功能
全網(wǎng)最全的 Android 音視頻和 OpenGL ES 干貨,都在這了
面試官:如何利用 Shader 實現(xiàn) RGBA 到 NV21 圖像格式轉(zhuǎn)換?
項目疑難問題解答、大廠內(nèi)部推薦、面試指導(dǎo)、簡歷指導(dǎo)、代碼指導(dǎo)、offer 選擇建議、學習路線規(guī)劃,可以點擊找我一對一解答。
