著色器圖像處理(邊緣檢測)

拉普拉斯算子(laplacian)

如果在圖像中一個較暗的區(qū)域中出現了一個亮點,那么用拉普拉斯運算就會使這個亮點變得更亮。

拉普拉斯變換效果:

  1. 強調圖像中灰度突變
  2. 降低灰度慢變化的區(qū)域

參考文檔https://wenku.baidu.com/view/23a4720a6c85ec3a87c2c598.html

拉普拉斯運算模板

0, 1, 0
1, -4, 1
0, 1, 0

當我們的每一個像素點通過拉普拉斯過濾后, 就會呈現邊緣化


precision highp float;
varying lowp vec2 varyTextCoord;
uniform sampler2D texMap;
uniform float stepValue;

const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);

// 卷積核大小
const int kernelSize = 9;
//0-0.009
void main()
{
    int i;
    vec4 sum = vec4(0.0);
    
    float Kernel[kernelSize];
    Kernel[6] = 0.0; Kernel[7] = 1.0; Kernel[8] = 0.0;
    Kernel[3] = 1.0; Kernel[4] = -4.0; Kernel[5] = 1.0;
    Kernel[0] = 0.0; Kernel[1] = 1.0; Kernel[2] = 0.0;
    
    float fStep = stepValue;
    vec2 Offset[kernelSize];
    Offset[0] = vec2(-fStep,-fStep); Offset[1] = vec2(0.0,-fStep); Offset[2] = vec2(fStep,-fStep);
    Offset[3] = vec2(-fStep,0.0);    Offset[4] = vec2(0.0,0.0);    Offset[5] = vec2(fStep,0.0);
    Offset[6] = vec2(-fStep, fStep); Offset[7] = vec2(0.0, fStep); Offset[8] = vec2(fStep, fStep);
    
    for (i = 0; i < kernelSize; i++)
    {
        vec4 tmp = texture2D(texMap, varyTextCoord.st + Offset[i]);
        sum += tmp * Kernel[i];
    }
    
    float luminance = dot(sum.rgb, W);

    gl_FragColor = vec4(vec3(luminance), 1.0);
}
灰度邊緣檢測

Sobel

邊檢測是一種十分經典的圖像處理技術,且可在片元著色器中方便地得以實現。邊檢測處理技:使用兩個Sobel過濾器,分別用于處理分量和垂直分量。前述內容已對Sobel過濾器有所提及,垂直Sob過濾器除了旋轉90°之外與水平Sobel過濾器相同。水平過濾器和垂直過濾器分別表示為:

-1, -2, -1
 0,  0,  0        
 1,  2,  1
 -1, 0, 1
 -2, 0, 2
 -1, 0, 1

Sobel過濾器比較間隔為一列(或行)的兩列數據(或兩行數據,取決于過濾器的類型),若存在邊,則顏色值之間彼此接近,過濾器將返回一個較小值。若返回值或數據值較大,則當前處理過程可判斷出邊的存在。該測試可在原始圖像或僅包含亮度值的圖像上進行。


precision highp float;
varying lowp vec2 varyTextCoord;
uniform sampler2D texMap;
/距離中心點多元的距離
uniform float stepValue;
//原色和灰度色的混合比例
uniform float ratioValue;

const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);

const int kernelSize = 9;
//0-0.009
void main()
{
    int i;
    float hSum = 0.0;
    float vSum = 0.0;
    vec3 irgb = texture2D( texMap,  varyTextCoord).rgb;
    vec4 color = vec4(0.0);

    float hKernel[kernelSize];
    hKernel[0] = -1.0; hKernel[1] = -2.0; hKernel[2] = -1.0;
    hKernel[3] = 0.0; hKernel[4] = 0.0; hKernel[5] = 0.0;
    hKernel[6] = 1.0; hKernel[7] = 2.0; hKernel[8] = 1.0;

    float vKernel[kernelSize];
    vKernel[0] = -1.0; vKernel[1] = 0.0; vKernel[2] = 1.0;
    vKernel[3] = -2.0; vKernel[4] = 0.0; vKernel[5] = 2.0;
    vKernel[6] = -1.0; vKernel[7] = 0.0; vKernel[8] = 1.0;

    float fStep = stepValue;
    vec2 Offset[kernelSize];
    Offset[0] = vec2(-fStep,-fStep); Offset[1] = vec2(0.0,-fStep); Offset[2] = vec2(fStep,-fStep);
    Offset[3] = vec2(-fStep,0.0);    Offset[4] = vec2(0.0,0.0);    Offset[5] = vec2(fStep,0.0);
    Offset[6] = vec2(-fStep, fStep); Offset[7] = vec2(0.0, fStep); Offset[8] = vec2(fStep, fStep);
    
    //水平soble過濾器
    for (i = 0; i < kernelSize; i++)
    {
        vec4 tmp = texture2D(texMap, varyTextCoord.st + Offset[i]);
        hSum += dot(tmp.rgb, W) * hKernel[i];
    }
     //垂直soble過濾器
    for (i = 0; i < kernelSize; i++)
    {
        vec4 tmp = texture2D(texMap, varyTextCoord.st + Offset[i]);
        vSum += dot(tmp.rgb, W) * vKernel[i];
    }

    float mag = sqrt( hSum*hSum + vSum*vSum);
    vec3 target = vec3( mag,mag,mag );
    color = vec4( mix( irgb, target, ratioValue), 1.);

    gl_FragColor = color;
}

混合函數是為了將邊緣的灰度與原色進行混合, 以達到彩色邊緣的效果

    color = vec4( mix( irgb, target, ratioValue), 1.);
原色灰度插值邊緣檢測
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容